home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.5 Applications 2004 April / SGI IRIX 6.5 Applications 2004 April.iso / dist / mpi.idb / usr / include / mpi++.h.z / mpi++.h
C/C++ Source or Header  |  2003-06-17  |  130KB  |  5,058 lines

  1. /* $Id: mpi++.h,v 1.7 2002/03/28 16:40:24 tmiller Exp $ */
  2. // -*- c++ -*-
  3. //
  4. // Copyright 1997-1999, University of Notre Dame.
  5. // Authors:  Jeremy G. Siek, Michael P. McNally, Jeffery M. Squyres, 
  6. //           Andrew Lumsdaine
  7. //
  8. // This file is part of the Notre Dame C++ bindings for MPI
  9. //
  10. // You should have received a copy of the License Agreement for the
  11. // Notre Dame C++ bindings for MPI along with the software;  see the
  12. // file LICENSE.mpi++.  If not, contact Office of Research, University of Notre
  13. // Dame, Notre Dame, IN  46556.
  14. //
  15. // Permission to modify the code and to distribute modified code is
  16. // granted, provided the text of this NOTICE is retained, a notice that
  17. // the code was modified is included with the above COPYRIGHT NOTICE and
  18. // with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
  19. // file is distributed with the modified code.
  20. //
  21. // LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
  22. // By way of example, but not limitation, Licensor MAKES NO
  23. // REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
  24. // PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
  25. // OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
  26. // OR OTHER RIGHTS.
  27. //
  28.  
  29. #ifndef MPIPP_H
  30. #define MPIPP_H
  31.  
  32. /* process-header: including mpi2c++_config.h */
  33.  
  34. #ifndef _MPIPP_CONFIG_H
  35. #define _MPIPP_CONFIG_H
  36.  
  37. #define _MPIPP_USEEXCEPTIONS_ 1
  38. #define _MPIPP_DEBUG_         0
  39.  
  40. #define MPI2CPP_HAVE_BOOL     1 
  41.  
  42. #define MPI_SGI_SIZEOF_INT            4
  43. #define SIZEOF_MPI2CPP_BOOL_T 1
  44.  
  45. #if MPI_SGI_SIZEOF_INT != SIZEOF_MPI2CPP_BOOL_T
  46. #define _MPIPP_BOOL_NE_INT_   1
  47. #else
  48. #define _MPIPP_BOOL_NE_INT_   0
  49. #endif
  50.  
  51. // Does our compiler support namespaces?
  52. #define _MPIPP_USENAMESPACE_  1
  53.  
  54. // Compile for Profiling?
  55. #define _MPIPP_PROFILING_     1
  56.  
  57. // What kind of signals do we have?
  58. #define MPI2CPP_BSD_SIGNAL    0
  59. #define MPI2CPP_SYSV_SIGNAL   1
  60.  
  61. // Is the ERR_PENDING constant defined?
  62. #define MPI2CPP_HAVE_PENDING  0
  63.  
  64. // Can virtual functions return derived class instead
  65. // of base class?
  66. #define VIRTUAL_FUNC_RET      0
  67.  
  68. // For mpich, tell it to use correct MPI_Handler_function definition
  69. #define USE_STDARG
  70.  
  71. #if _MPIPP_PROFILING_
  72. #define _REAL_MPI_ PMPI
  73. #else
  74. #define _REAL_MPI_ MPI
  75. #endif
  76.  
  77. #if _MPIPP_USENAMESPACE_
  78. #define _MPIPP_STATIC_
  79. #define _MPIPP_EXTERN_ extern
  80. #else
  81. #define _MPIPP_STATIC_ static
  82. #define _MPIPP_EXTERN_
  83. #endif
  84.  
  85. #if MPI2CPP_HAVE_BOOL
  86. typedef bool MPI2CPP_BOOL_T;
  87. #define MPI2CPP_FALSE false
  88. #define MPI2CPP_TRUE true
  89. #else
  90. enum MPI2CPP_BOOL_T { MPI2CPP_FALSE, MPI2CPP_TRUE };
  91. #ifdef bool
  92. /* 1 line(s) elided by process-header */
  93. #endif
  94. #ifdef false
  95. /* 1 line(s) elided by process-header */
  96. #endif
  97. #ifdef true
  98. /* 1 line(s) elided by process-header */
  99. #endif
  100. #define bool MPI2CPP_BOOL_T
  101. #define false MPI2CPP_FALSE
  102. #define true MPI2CPP_TRUE
  103. #endif
  104.  
  105. #define MPI2CPP_BSD_SIGNAL 0
  106. #define MPI2CPP_SYSV_SIGNAL 1
  107.  
  108. // Flags for FORTRAN, optional C, and optional Fortran datatypes
  109.  
  110. #define MPI2CPP_FORTRAN 1
  111. #define MPI2CPP_ALL_OPTIONAL_FORTRAN 0
  112. #define MPI2CPP_SOME_OPTIONAL_FORTRAN 1
  113. #define MPI2CPP_OPTIONAL_C 0
  114.  
  115. //
  116. // Architecture/OS's that will need flags in the test suite to
  117. // ignore certain tests
  118. //
  119.  
  120. #define MPI2CPP_LAM61 0
  121. #define MPI2CPP_LAM62 0
  122. #define MPI2CPP_LAM63 0
  123. #define MPI2CPP_LAMUNKNOWN 0
  124.  
  125. #define MPI2CPP_MPICH1013 0
  126. #define MPI2CPP_MPICH110 0
  127. #define MPI2CPP_MPICH111 0
  128. #define MPI2CPP_MPICH112 0
  129. #define MPI2CPP_MPICHUNKNOWN 0
  130.  
  131. #define MPI2CPP_IBM21014 0
  132. #define MPI2CPP_IBM21015 0
  133. #define MPI2CPP_IBM21016 0
  134. #define MPI2CPP_IBM21017 0
  135. #define MPI2CPP_IBM21018 0
  136. #define MPI2CPP_IBMUNKNOWN 0
  137. #define MPI2CPP_IBM_SP (MPI2CPP_IBM21014 | MPI2CPP_IBM21015 | MPI2CPP_IBM21016 | MPI2CPP_IBM21017 | MPI2CPP_IBM21018 | MPI2CPP_IBMUNKNOWN)
  138.  
  139. #define MPI2CPP_SGI20 0
  140. #define MPI2CPP_SGI30 0
  141. #define MPI2CPP_SGIUNKNOWN 1
  142.  
  143. #define MPI2CPP_HPUX0102 0
  144. #define MPI2CPP_HPUX0103 0
  145. #define MPI2CPP_HPUX0105 0
  146. #define MPI2CPP_HPUXUNKNOWN 0
  147.  
  148. #define MPI2CPP_CRAY 0
  149. #define MPI2CPP_CRAY1104 0
  150. #define MPI2CPP_CRAYUNKNWON 0
  151.  
  152. #define MPI2CPP_G_PLUS_PLUS 0
  153.  
  154. #define MPI2CPP_ATTR long
  155.  
  156. // #$%@#%@#%@#% AIX!!!!
  157.  
  158. #define MPI2CPP_AIX 0
  159.  
  160. #endif
  161. /* process-header: end of mpi2c++_config.h */
  162.  
  163. extern "C" {
  164. #include <mpi.h>
  165. }
  166.  
  167. #if defined(_STANDARD_C_PLUS_PLUS)
  168. #include <iostream>
  169. #else
  170. #include <iostream.h>
  171. #endif
  172. #include <stdarg.h>
  173. /* process-header: including mpi2c++_map.h */
  174.  
  175.  
  176. #ifndef MAP_H_
  177. #define MAP_H_
  178.  
  179. /* process-header: including mpi2c++_list.h */
  180.  
  181.  
  182. #ifndef LIST_H_
  183. #define LIST_H_
  184.  
  185. /* process-header: including mpi2c++_config.h */
  186.  
  187. #ifndef _MPIPP_CONFIG_H
  188. /* 111 line(s) elided by process-header */
  189. #endif
  190. /* process-header: end of mpi2c++_config.h */
  191.  
  192. class MPI_SGI_List {
  193. public:
  194.   typedef void* Data;
  195.   class iter;
  196.  
  197.   class Link {
  198.     friend class MPI_SGI_List;
  199.     friend class iter;
  200.     Data data;
  201.     Link *next;
  202.     Link *prev;
  203.     Link() { }
  204.     Link(Data d, Link* p, Link* n) : data(d), next(n), prev(p) { }
  205.   };
  206.  
  207.   class iter {
  208.     friend class MPI_SGI_List;
  209.     Link* node;
  210.   public:
  211.     iter(Link* n) : node(n) { }
  212.     iter& operator++() { node = node->next; return *this; }
  213.     iter operator++(int) { iter tmp = *this; ++(*this); return tmp; }
  214.     Data& operator*() const { return node->data; }
  215.     MPI2CPP_BOOL_T operator==(const iter& x) const { return (MPI2CPP_BOOL_T)(node == x.node); }
  216.     MPI2CPP_BOOL_T operator!=(const iter& x) const { return (MPI2CPP_BOOL_T)(node != x.node); }
  217.   };
  218.   
  219.   MPI_SGI_List() { _end.prev = &_end; _end.next = &_end; }
  220.   virtual ~MPI_SGI_List() {
  221.     for (iter i = begin(); i != end(); ) {
  222.       Link* garbage = i.node; i++;
  223.       delete garbage;
  224.     }
  225.   }
  226.   virtual iter begin() { return _end.next; }
  227.   virtual iter end() { return &_end; }
  228.   virtual iter insert(iter p, Data d) {
  229.     iter pos(p);
  230.     Link* n = new Link(d, pos.node->prev, pos.node);
  231.     pos.node->prev->next = n;
  232.     pos.node->prev = n;
  233.     return n;
  234.   }
  235.   void erase(iter pos) {
  236.     pos.node->prev->next = pos.node->next;
  237.     pos.node->next->prev = pos.node->prev;
  238.     delete pos.node;
  239.   }
  240.  
  241. protected:
  242.   Link _end;
  243. };
  244.  
  245. #endif
  246.  
  247.  
  248.  
  249.  
  250. /* process-header: end of mpi2c++_list.h */
  251. typedef MPI_SGI_List Container;
  252.  
  253. class MPI_SGI_Map {
  254.   Container c;
  255. public:
  256.  
  257.   typedef void* address;
  258.   typedef MPI_SGI_List::iter iter;
  259.  
  260.   struct Pair {
  261.     Pair(address f, address s) : first(f), second(s) {}
  262.     Pair() : first(0), second(0) { }
  263.     address first;
  264.     address second;
  265.   };
  266.  
  267.   MPI_SGI_Map() { }
  268.  
  269.   ~MPI_SGI_Map() {
  270.     for (iter i = c.end(); i != c.end(); i++) {
  271.       delete (Pair*)(*i);
  272.     }
  273.   }
  274.   
  275.   Pair* begin();
  276.   Pair* end();
  277.   
  278.   address& operator[](address key)
  279.   {
  280.     address* found = (address*)0;
  281.     for (iter i = c.begin(); i != c.end(); i++) {
  282.       if (((Pair*)*i)->first == key)
  283.     found = &((Pair*)*i)->second;
  284.     }
  285.     if (! found) {
  286.       iter tmp = c.insert(c.begin(), new Pair(key,0));
  287.       found = &((Pair*)*tmp)->second;
  288.     }
  289.     return *found;
  290.   }
  291.  
  292.   void erase(address key)
  293.   {
  294.     for (iter i = c.begin(); i != c.end(); i++) {
  295.       if (((Pair*)*i)->first == key) {
  296.     delete (Pair*)*i;
  297.     c.erase(i); break;
  298.       }
  299.     }
  300.   }
  301. };
  302.  
  303. #endif
  304.  
  305.  
  306.  
  307.  
  308. /* process-header: end of mpi2c++_map.h */
  309.  
  310.  
  311.  
  312. //JGS: this is used for implementing user functions for MPI::Op
  313. extern void
  314. op_intercept(void *invec, void *outvec, int *len, MPI_Datatype *datatype);
  315.  
  316. #if MPI2CPP_IBM_SP
  317. //Here's the sp2 typedeffrom their header file:
  318. //  typedef void MPI_Handler_function(MPI_Comm *,int *,char *,int *,int *);
  319. extern void
  320. errhandler_intercept(MPI_Comm * mpi_comm, int * err, char*, int*, int*);
  321.  
  322. extern void
  323. throw_excptn_fctn(MPI_Comm* comm, int* errcode, char*, int*, int*);
  324.  
  325.  
  326. #else
  327.  
  328. //JGS: this is used as the MPI_Handler_function for
  329. // the mpi_errhandler in ERRORS_THROW_EXCEPTIONS
  330. extern void
  331. throw_excptn_fctn(MPI_Comm* comm, int* errcode, ...);
  332.  
  333. extern void
  334. errhandler_intercept(MPI_Comm * mpi_comm, int * err, ...);
  335. #endif
  336.  
  337.  
  338. //used for attr intercept functions
  339. enum CommType { eIntracomm, eIntercomm, eCartcomm, eGraphcomm};
  340.  
  341. extern int
  342. copy_attr_intercept(MPI_Comm oldcomm, int keyval, 
  343.             void *extra_state, void *attribute_val_in, 
  344.             void *attribute_val_out, int *flag);
  345.  
  346. extern int
  347. delete_attr_intercept(MPI_Comm comm, int keyval, 
  348.               void *attribute_val, void *extra_state);
  349.  
  350.  
  351. #if _MPIPP_PROFILING_
  352. /* process-header: including pmpi++.h */
  353.  
  354.  
  355. #ifndef PMPIPP_H
  356. #define PMPIPP_H
  357.  
  358.  
  359. #if _MPIPP_USENAMESPACE_
  360. namespace PMPI {
  361. #else
  362. class PMPI {
  363. public:
  364. #endif
  365.  
  366.  
  367. #if ! _MPIPP_USEEXCEPTIONS_
  368.   _MPIPP_EXTERN_ _MPIPP_STATIC_ int errno;
  369. #endif
  370.  
  371.   class Comm_Null;
  372.   class Comm;
  373.   class Intracomm;
  374.   class Intercomm;
  375.   class Graphcomm;
  376.   class Cartcomm;
  377.   class Datatype;
  378.   class Errhandler;
  379.   class Group;
  380.   class Op;
  381.   class Request;
  382.   class Status;
  383.  
  384.   typedef MPI_Aint Aint;
  385.  
  386. /* process-header: including functions.h */
  387.  
  388. //
  389. // Point-to-Point Communication
  390. //
  391.  
  392. _MPIPP_STATIC_ void 
  393. Attach_buffer(void* buffer, int size);
  394.  
  395. _MPIPP_STATIC_ int 
  396. Detach_buffer(void*& buffer);
  397.  
  398. //
  399. // Process Topologies
  400. //
  401.  
  402. _MPIPP_STATIC_ void
  403. Compute_dims(int nnodes, int ndims, int dims[]);
  404.  
  405. //
  406. // Environmental Inquiry
  407. //
  408.  
  409. _MPIPP_STATIC_ void 
  410. Get_processor_name(char*& name, int& resultlen);
  411.  
  412. _MPIPP_STATIC_ void
  413. Get_error_string(int errorcode, char*& string, int& resultlen);
  414.  
  415. _MPIPP_STATIC_ int 
  416. Get_error_class(int errorcode);
  417.  
  418. _MPIPP_STATIC_ double 
  419. Wtime();
  420.  
  421. _MPIPP_STATIC_ double 
  422. Wtick();
  423.  
  424. _MPIPP_STATIC_ void
  425. Init(int& argc, char**& argv);
  426.  
  427. _MPIPP_STATIC_ void
  428. Init();
  429.  
  430. _MPIPP_STATIC_ void
  431. Real_init();
  432.  
  433. _MPIPP_STATIC_ void
  434. Finalize();
  435.  
  436. _MPIPP_STATIC_ MPI2CPP_BOOL_T
  437. Is_initialized();
  438.  
  439. //
  440. // Profiling
  441. //
  442.  
  443. _MPIPP_STATIC_ void
  444. Pcontrol(const int level, ...);
  445.  
  446.  
  447. // JGS defer to MPI-2
  448. //inline _MPIPP_STATIC_ void
  449. //Get_version(int& version, int& subversion);
  450.  
  451. _MPIPP_STATIC_ _REAL_MPI_::Aint
  452. Get_address(void* location);
  453. /* process-header: end of functions.h */
  454. /* process-header: including pdatatype.h */
  455.  
  456.  
  457. class Datatype {
  458. public:
  459.   // construction / destruction
  460.   inline Datatype() : mpi_datatype(MPI_DATATYPE_NULL) { }
  461.   inline virtual ~Datatype() {}
  462.   // inter-language operability
  463.   inline Datatype(const MPI_Datatype &i) : mpi_datatype(i) { }
  464.  
  465.   // copy / assignment
  466.   Datatype(const Datatype& dt) : mpi_datatype(dt.mpi_datatype) { }
  467.  
  468.   Datatype& operator=(const Datatype& dt) {
  469.     mpi_datatype = dt.mpi_datatype; return *this;
  470.   }
  471.   
  472.   // comparison
  473.   MPI2CPP_BOOL_T operator==(const Datatype &a) const {
  474.     return (MPI2CPP_BOOL_T) (mpi_datatype == a.mpi_datatype);
  475.   }
  476.  
  477.   inline MPI2CPP_BOOL_T operator!= (const Datatype &a) const 
  478.     { return (MPI2CPP_BOOL_T) !(*this == a); }
  479.  
  480.   // inter-language operability
  481.   inline Datatype& operator= (const MPI_Datatype &i) 
  482.     { mpi_datatype = i; return *this; }
  483.  
  484.   inline operator MPI_Datatype () const { return mpi_datatype; }
  485.  
  486.   inline const MPI_Datatype& mpi() const { return mpi_datatype; }
  487.  
  488.   //
  489.   // Point-to-Point Communication
  490.   //
  491.  
  492.   inline virtual Datatype Create_contiguous(int count) const;
  493.  
  494.   virtual Datatype Create_vector(int count, int blocklength,
  495.                     int stride) const;
  496.  
  497.   virtual Datatype Create_indexed(int count,
  498.                        const int array_of_blocklengths[], 
  499.                        const int array_of_displacements[]) const;
  500.   
  501.   static Datatype Create_struct(int count, const int array_of_blocklengths[],
  502.                      const Aint array_of_displacements[],
  503.                      const Datatype array_if_types[]);
  504.   
  505.  
  506.   virtual Datatype Create_hindexed(int count, const int array_of_blocklengths[],
  507.                     const Aint array_of_displacements[]) const;
  508.  
  509.   virtual Datatype Create_hvector(int count, int blocklength,
  510.                        Aint stride) const;
  511.  
  512.   virtual int Get_size() const;
  513.  
  514.   virtual void Get_extent(Aint& lb, Aint& extent) const;
  515.  
  516.   virtual void Commit();
  517.  
  518.   virtual void Free();
  519.  
  520.   //JGS I did not make these inline becuase of the dependency
  521.   //on the Comm conversion function
  522.   virtual void Pack(const void* inbuf, int incount, void *outbuf, 
  523.             int outsize, int& position, const Comm &comm) const;
  524.   virtual void Unpack(const void* inbuf, int insize, void *outbuf,
  525.               int outcount, int& position, const Comm& comm) const;
  526.   virtual int Pack_size(int incount, const Comm& comm) const;
  527.  
  528. protected:
  529.   MPI_Datatype mpi_datatype;
  530.  
  531. };
  532. /* process-header: end of pdatatype.h */
  533.  
  534.   typedef void User_function(const void* invec, void* inoutvec, int len,
  535.                  const Datatype& datatype);
  536.  
  537. /* process-header: including pexception.h */
  538.  
  539.  
  540. class Exception {
  541. public:
  542.   inline Exception(int ec) : error_code(ec) {
  543.     (void)MPI_Error_class(error_code, &error_class);
  544.     int resultlen;
  545.     error_string = new char[MPI_MAX_ERROR_STRING];
  546.     (void)MPI_Error_string(error_code, error_string, &resultlen);
  547.   }
  548.  
  549.   inline int Get_error_code() const { return error_code; }
  550.  
  551.   inline int Get_error_class() const { return error_class; }
  552.   
  553.   inline const char* Get_error_string() const { return error_string; }
  554.   
  555. protected:
  556.   int error_code;
  557.   char* error_string;
  558.   int error_class;
  559. };
  560. /* process-header: end of pexception.h */
  561. /* process-header: including pop.h */
  562.  
  563.  
  564. class Op {
  565. public:
  566.   // construction
  567.   Op() : mpi_op(MPI_OP_NULL) { }
  568.  
  569.   Op(const Op& op) : mpi_op(op.mpi_op), op_user_function(op.op_user_function) { }
  570.  
  571.   Op(const MPI_Op &i) : mpi_op(i) { }
  572.  
  573.   // destruction
  574.   virtual ~Op() { }
  575.  
  576.   // assignment
  577.   Op& operator=(const Op& op);
  578.   Op& operator= (const MPI_Op &i);
  579.   // comparison
  580.   MPI2CPP_BOOL_T operator== (const Op &a);
  581.   MPI2CPP_BOOL_T operator!= (const Op &a);
  582.   // conversion functions for inter-language operability
  583.   operator MPI_Op () const;
  584.   //  operator MPI_Op* () const;
  585.  
  586.   // Collective Communication  (defined in op_inln.h)
  587.   virtual void Init(User_function *func, MPI2CPP_BOOL_T commute);
  588.   virtual void Free(void);
  589.  
  590.   User_function *op_user_function;
  591.  
  592. protected:
  593.   MPI_Op mpi_op;
  594.  
  595. };
  596.  
  597. /* process-header: end of pop.h */
  598. /* process-header: including pstatus.h */
  599.  
  600.  
  601. class Status {
  602.   friend class PMPI::Comm; //so I can access pmpi_status data member in comm.cc
  603.   friend class PMPI::Request; //and also from request.cc
  604.  
  605. public:
  606.   // construction
  607.   inline Status() { }
  608.   // copy
  609.   Status(const Status& data) : mpi_status(data.mpi_status) { }
  610.  
  611.   inline Status(const MPI_Status &i) : mpi_status(i) { }
  612.  
  613.   inline virtual ~Status() {}
  614.  
  615.   Status& operator=(const Status& data) {
  616.     mpi_status = data.mpi_status; return *this;
  617.   } 
  618.  
  619.   // comparison, don't need for status
  620.  
  621.   // inter-language operability
  622.   inline Status& operator= (const MPI_Status &i) {
  623.     mpi_status = i; return *this; }
  624.   inline operator MPI_Status () const { return mpi_status; }
  625.   inline operator MPI_Status* () const { return (MPI_Status*)&mpi_status; }
  626.  
  627.   //
  628.   // Point-to-Point Communication
  629.   //
  630.  
  631.   inline virtual int Get_count(const Datatype& datatype) const;
  632.  
  633.   inline virtual MPI2CPP_BOOL_T Is_cancelled() const;
  634.  
  635.   virtual int Get_elements(const Datatype& datatype) const;
  636.  
  637.   //
  638.   // Status Access
  639.   //
  640.   inline virtual int Get_source() const;
  641.  
  642.   inline virtual void Set_source(int source);
  643.   
  644.   inline virtual int Get_tag() const;
  645.  
  646.   inline virtual void Set_tag(int tag);
  647.   
  648.   inline virtual int Get_error() const;
  649.  
  650.   inline virtual void Set_error(int error);
  651.   
  652. protected:
  653.   MPI_Status mpi_status;
  654.  
  655. };
  656. /* process-header: end of pstatus.h */
  657. /* process-header: including prequest.h */
  658.  
  659.  
  660. class Request {
  661. public:
  662.   // construction / destruction
  663.   Request(void) { }
  664.   virtual ~Request() {}
  665.   Request(const MPI_Request &i) : mpi_request(i) { }
  666.  
  667.   // copy / assignment
  668.   Request(const Request& r) : mpi_request(r.mpi_request) { }
  669.  
  670.   Request& operator=(const Request& r) {
  671.     mpi_request = r.mpi_request;
  672.     return *this;
  673.   }
  674.  
  675.   // comparison
  676.   MPI2CPP_BOOL_T operator== (const Request &a)
  677.   { return (MPI2CPP_BOOL_T)(mpi_request == a.mpi_request); }
  678.   MPI2CPP_BOOL_T operator!= (const Request &a) 
  679.   { return (MPI2CPP_BOOL_T)!(*this == a); }
  680.  
  681.   // inter-language operability
  682.   Request& operator= (const MPI_Request &i) {
  683.     mpi_request = i; return *this; }
  684.   operator MPI_Request () const { return mpi_request; }
  685.   operator MPI_Request* () const { return (MPI_Request*)&mpi_request; }
  686.  
  687.   //
  688.   // Point-to-Point Communication
  689.   //
  690.  
  691.   virtual void Wait(Status &status);
  692.  
  693.   virtual void Wait();
  694.  
  695.   virtual MPI2CPP_BOOL_T Test(Status &status);
  696.  
  697.   virtual MPI2CPP_BOOL_T Test();
  698.  
  699.   virtual void Free(void);
  700.  
  701.   static int Waitany(int count, Request array[], Status& status);
  702.  
  703.   static int Waitany(int count, Request array[]);
  704.  
  705.   static MPI2CPP_BOOL_T Testany(int count, Request array[], int& index, Status& status);
  706.  
  707.   static MPI2CPP_BOOL_T Testany(int count, Request array[], int& index);
  708.  
  709.   static void Waitall(int count, Request req_array[], Status stat_array[]);
  710.  
  711.   static void Waitall(int count, Request req_array[]);
  712.  
  713.   static MPI2CPP_BOOL_T Testall(int count, Request req_array[], Status stat_array[]);
  714.  
  715.   static MPI2CPP_BOOL_T Testall(int count, Request req_array[]);
  716.  
  717.   static int Waitsome(int incount, Request req_array[],
  718.                  int array_of_indices[], Status stat_array[]);
  719.  
  720.   static int Waitsome(int incount, Request req_array[],
  721.                  int array_of_indices[]);
  722.  
  723.   static int Testsome(int incount, Request req_array[],
  724.                  int array_of_indices[], Status stat_array[]);
  725.  
  726.   static int Testsome(int incount, Request req_array[],
  727.                  int array_of_indices[]);
  728.  
  729.   virtual void Cancel(void) const;
  730.  
  731. protected:
  732.   MPI_Request mpi_request;
  733.  
  734. private:
  735.   static Status ignored_status;
  736.   
  737. };
  738.  
  739.  
  740. class Prequest : public Request {
  741. public:
  742.  
  743.   Prequest() { }
  744.  
  745.   Prequest(const Prequest& p) : Request(p) { }
  746.   
  747.   Prequest(const MPI_Request &i) : Request(i) { }
  748.  
  749.   virtual ~Prequest() { }
  750.  
  751.   virtual void Start();
  752.  
  753.   static void Startall(int count, Prequest array_of_requests[]);
  754.  
  755. };
  756. /* process-header: end of prequest.h */
  757. /* process-header: including pgroup.h */
  758.  
  759. class Group {
  760. public:
  761.   // construction / destruction
  762.   inline Group() : mpi_group(MPI_GROUP_NULL) { }
  763.   inline virtual ~Group() {}
  764.   inline Group(const MPI_Group &i) : mpi_group(i) { }
  765.  
  766.   // copy / assignment
  767.   Group(const Group& g): mpi_group(g.mpi_group) { }
  768.  
  769.   Group& operator=(const Group& g) {
  770.     mpi_group = g.mpi_group;
  771.     return *this;
  772.   }
  773.  
  774.   // comparison
  775.   MPI2CPP_BOOL_T operator== (const Group &a) {
  776.     return (MPI2CPP_BOOL_T)(mpi_group == a.mpi_group);
  777.   }
  778.   MPI2CPP_BOOL_T operator!= (const Group &a) { return (MPI2CPP_BOOL_T)!(*this == a); }
  779.  
  780.   // inter-language operability
  781.   inline Group& operator= (const MPI_Group &i) { mpi_group = i; return *this; }
  782.   inline operator const MPI_Group& () const { return mpi_group; }
  783.   inline operator MPI_Group* () const { return (MPI_Group*)&mpi_group; }
  784.  
  785.   inline const MPI_Group& mpi() const { return mpi_group; }
  786.   //
  787.   // Groups, Contexts, and Communicators
  788.   //
  789.  
  790.   virtual int Get_size() const;
  791.   
  792.   virtual int Get_rank() const;
  793.  
  794.   static void Translate_ranks(const Group& group1, int n, const int ranks1[], 
  795.                   const Group& group2, int ranks2[]);
  796.   
  797.   static int Compare(const Group& group1, const Group& group2);
  798.  
  799.   static Group Union(const Group &group1, const Group &group2);
  800.  
  801.   static Group Intersect(const Group &group1, const Group &group2);
  802.  
  803.   static Group Difference(const Group &group1, const Group &group2);
  804.  
  805.   virtual Group Incl(int n, const int ranks[]) const;
  806.  
  807.   virtual Group Excl(int n, const int ranks[]) const;
  808.  
  809.   virtual Group Range_incl(int n, const int ranges[][3]) const;
  810.  
  811.   virtual Group Range_excl(int n, const int ranges[][3]) const;
  812.  
  813.   virtual void Free();
  814.  
  815. protected:
  816.   MPI_Group mpi_group;
  817.  
  818. };
  819.  
  820. /* process-header: end of pgroup.h */
  821. /* process-header: including pcomm.h */
  822.  
  823. class Comm_Null {
  824. public:
  825.  
  826.   // construction
  827.   Comm_Null() : mpi_comm(MPI_COMM_NULL) { }
  828.   // copy
  829.   Comm_Null(const Comm_Null& data) : mpi_comm(data.mpi_comm) { }
  830.   // inter-language operability  
  831.   Comm_Null(const MPI_Comm& data) : mpi_comm(data) { }
  832.  
  833.   // destruction
  834.   //JGS  virtual ~Comm_Null() { }
  835.  
  836.  // comparison
  837.   // JGS make sure this is right (in other classes too)
  838.   MPI2CPP_BOOL_T operator==(const Comm_Null& data) const {
  839.     return (MPI2CPP_BOOL_T) (mpi_comm == data.mpi_comm); }
  840.  
  841.   MPI2CPP_BOOL_T operator!=(const Comm_Null& data) const {
  842.     return (MPI2CPP_BOOL_T) !(*this == data);}
  843.  
  844.   // inter-language operability (conversion operators)
  845.   operator MPI_Comm() const { return mpi_comm; }
  846.   operator MPI_Comm*() /*const JGS*/ { return &mpi_comm; }
  847.  
  848. protected:
  849.   MPI_Comm mpi_comm;
  850. };
  851.  
  852. class Comm : public Comm_Null {
  853.  
  854. #if 0 // JGS getting rid of !@(&!$@ friends, justing making some stuff public
  855. #if _MPIPP_USENAMESPACE_
  856. #if IBM_SP
  857.   friend void ::errhandler_intercept(MPI_Comm * mpi_comm, int * err, char*, int*, int*);
  858.  
  859. #else
  860.   friend void ::errhandler_intercept(MPI_Comm * mpi_comm, int* err, ...);
  861. #endif
  862.   friend int ::copy_attr_intercept(MPI_Comm oldcomm, int keyval, 
  863.                    void *extra_state, void *attribute_val_in, 
  864.                    void *attribute_val_out, int *flag);
  865.   friend int ::delete_attr_intercept(MPI_Comm comm, int keyval, 
  866.                      void *attribute_val, void *extra_state);
  867. #endif
  868.  
  869. #if ! _MPIPP_USENAMESPACE_
  870.  
  871. #if IBM_SP
  872.   friend void errhandler_intercept(MPI_Comm * mpi_comm, int * err, char*, int*, int*);
  873. #else
  874.   friend void errhandler_intercept(MPI_Comm * mpi_comm, int* err, ...);
  875. #endif
  876.   friend int copy_attr_intercept(MPI_Comm oldcomm, int keyval, 
  877.                  void *extra_state, void *attribute_val_in, 
  878.                  void *attribute_val_out, int *flag);
  879.   friend int delete_attr_intercept(MPI_Comm comm, int keyval, 
  880.                    void *attribute_val, void *extra_state);
  881. #endif
  882. #endif
  883.  
  884. public:
  885.  
  886.   // $%^#$%^#$^ g++ 2.7.2!!! We have to rename these functions because
  887.   // g++ does not scope properly.  It somehow loses the outter class (MPI
  888.   // or PMPI) -- remember, g++ does not do namespaces! -- and thinks that 
  889.   // we are conflicting with Errhandler_fn et al. in comm.h
  890.   // @#$%@#$@#%$@#% g++!!
  891.   typedef void PMPI_Errhandler_fn(Comm&, int*, ...);
  892.   typedef int PMPI_Copy_attr_function(const Comm& oldcomm, int comm_keyval,
  893.                       void* extra_state, void* attribute_val_in,
  894.                       void* attribute_val_out, MPI2CPP_BOOL_T& flag);
  895.   typedef int PMPI_Delete_attr_function(Comm& comm, int comm_keyval, 
  896.                     void* attribute_val, void* extra_state);
  897. #define ERRHANDLERFN PMPI_Errhandler_fn
  898. #define COPYATTRFN PMPI_Copy_attr_function
  899. #define DELETEATTRFN PMPI_Delete_attr_function
  900.  
  901.   // construction
  902.   Comm() { }
  903.   // copy
  904.   Comm(const Comm_Null& data) : Comm_Null(data) { }
  905.   // inter-language operability  
  906.   Comm(const MPI_Comm& data) : Comm_Null(data) { }
  907.  
  908.   //
  909.   // Point-to-Point
  910.   //
  911.  
  912.   virtual void Send(const void *buf, int count, 
  913.             const Datatype & datatype, int dest, int tag) const;
  914.  
  915.   virtual void Recv(void *buf, int count, const Datatype & datatype,
  916.             int source, int tag, Status & status) const;
  917.  
  918.   virtual void Recv(void *buf, int count, const Datatype & datatype,
  919.             int source, int tag) const;
  920.   
  921.   virtual void Bsend(const void *buf, int count,
  922.              const Datatype & datatype, int dest, int tag) const;
  923.   
  924.   virtual void Ssend(const void *buf, int count, 
  925.              const Datatype & datatype, int dest, int tag) const;
  926.   
  927.   virtual void Rsend(const void *buf, int count,
  928.              const Datatype & datatype, int dest, int tag) const;
  929.   
  930.   virtual Request Isend(const void *buf, int count,
  931.                  const Datatype & datatype,
  932.                  int dest, int tag) const;
  933.  
  934.   virtual Request Ibsend(const void *buf, int count, const
  935.                   Datatype & datatype, int dest, int tag) const;
  936.  
  937.   virtual Request Issend(const void *buf, int count,
  938.                   const Datatype & datatype, int dest, int tag) const;
  939.   
  940.   virtual Request Irsend(const void *buf, int count,
  941.                   const Datatype & datatype, int dest, int tag) const;
  942.   
  943.   virtual Request Irecv(void *buf, int count,
  944.                  const Datatype & datatype, int source, int tag) const;
  945.  
  946.   virtual MPI2CPP_BOOL_T Iprobe(int source, int tag, Status & status) const;
  947.   
  948.   virtual MPI2CPP_BOOL_T Iprobe(int source, int tag) const;
  949.  
  950.   virtual void Probe(int source, int tag, Status & status) const;
  951.  
  952.   virtual void Probe(int source, int tag) const;
  953.  
  954.   virtual Prequest Send_init(const void *buf, int count,
  955.                   const  Datatype & datatype,
  956.                   int dest, int tag) const;
  957.  
  958.   virtual Prequest Bsend_init(const void *buf, int count,
  959.                    const Datatype & datatype,
  960.                    int dest, int tag) const;
  961.   
  962.   virtual Prequest Ssend_init(const void *buf, int count,
  963.                    const Datatype & datatype,
  964.                    int dest, int tag) const;
  965.   
  966.   virtual Prequest Rsend_init(const void *buf, int count,
  967.                    const Datatype & datatype,
  968.                    int dest, int tag) const;
  969.  
  970.   virtual Prequest Recv_init(void *buf, int count,
  971.                   const Datatype & datatype,
  972.                   int source, int tag) const;
  973.   
  974.   virtual void Sendrecv(const void *sendbuf, int sendcount,
  975.             const Datatype & sendtype, int dest, int sendtag, 
  976.             void *recvbuf, int recvcount, 
  977.             const Datatype & recvtype, int source,
  978.             int recvtag, Status & status) const;
  979.  
  980.   virtual void Sendrecv(const void *sendbuf, int sendcount,
  981.             const Datatype & sendtype, int dest, int sendtag, 
  982.             void *recvbuf, int recvcount, 
  983.             const Datatype & recvtype, int source,
  984.             int recvtag) const;
  985.  
  986.   virtual void Sendrecv_replace(void *buf, int count,
  987.                 const Datatype & datatype, int dest, 
  988.                 int sendtag, int source,
  989.                 int recvtag, Status & status) const;
  990.  
  991.   virtual void Sendrecv_replace(void *buf, int count,
  992.                 const Datatype & datatype, int dest, 
  993.                 int sendtag, int source,
  994.                 int recvtag) const;
  995.  
  996.   //
  997.   // Groups, Contexts, and Communicators
  998.   //
  999.   
  1000.   virtual Group Get_group() const;
  1001.   
  1002.   virtual int Get_size() const;
  1003.   
  1004.   virtual int Get_rank() const;
  1005.  
  1006.   static int Compare(const Comm & comm1, const Comm & comm2);
  1007.  
  1008.   virtual void Free(void);
  1009.   
  1010.   virtual MPI2CPP_BOOL_T Is_inter() const;
  1011.   
  1012.   //
  1013.   //Process Topologies
  1014.   //
  1015.  
  1016.   virtual int Get_topology() const;
  1017.   
  1018.   //
  1019.   // Environmental Inquiry
  1020.   //
  1021.  
  1022.   virtual void Abort(int errorcode);
  1023.  
  1024.   virtual void Set_errhandler(const Errhandler& errhandler);
  1025.  
  1026.   virtual Errhandler Get_errhandler() const;
  1027.  
  1028.   static Errhandler Create_errhandler(PMPI_Errhandler_fn* function);
  1029.  
  1030.   //
  1031.   // Keys and Attributes
  1032.   //
  1033.  
  1034.   static int Create_keyval(PMPI_Copy_attr_function*,
  1035.                PMPI_Delete_attr_function*,
  1036.                void*);
  1037.   
  1038.   static void Free_keyval(int& comm_keyval);
  1039.   
  1040.   virtual void Set_attr(int comm_keyval, const void* attribute_val) const;
  1041.   
  1042.   virtual MPI2CPP_BOOL_T Get_attr(int comm_keyval, void* attribute_val) const;
  1043.   
  1044.   virtual void Delete_attr(int comm_keyval);
  1045.   
  1046.   static int NULL_COPY_FN(const PMPI::Comm& oldcomm, int comm_keyval,
  1047.               void* extra_state, void* attribute_val_in,
  1048.               void* attribute_val_out, MPI2CPP_BOOL_T& flag);
  1049.   
  1050.   static int DUP_FN(const Comm& oldcomm, int comm_keyval,
  1051.             void* extra_state, void* attribute_val_in,
  1052.             void* attribute_val_out, MPI2CPP_BOOL_T& flag);
  1053.   
  1054.   static int NULL_DELETE_FN(Comm& comm, int comm_keyval, void* attribute_val,
  1055.                 void* extra_state);
  1056. private:
  1057.   static Status ignored_status;
  1058. public: // JGS friends cause portability problems
  1059.   static MPI_SGI_Map mpi_comm_map;
  1060.   static MPI_SGI_Map key_fn_map;
  1061.   Errhandler* my_errhandler;
  1062.  
  1063. };
  1064.  
  1065. /* process-header: end of pcomm.h */
  1066. /* process-header: including perrhandler.h */
  1067.  
  1068. class Errhandler {
  1069. #if 0
  1070.   friend void Real_init();  //see function init below
  1071. #endif
  1072. public:
  1073.   // construction
  1074.   inline Errhandler()
  1075.     : mpi_errhandler(MPI_ERRHANDLER_NULL) {}
  1076.   // inter-language operability
  1077.   inline Errhandler(const MPI_Errhandler &i)
  1078.     : mpi_errhandler(i) {}
  1079.   // copy
  1080.   inline Errhandler(const Errhandler& e);
  1081.  
  1082.   inline virtual ~Errhandler() {}
  1083.  
  1084.   inline Errhandler& operator=(const Errhandler& e);
  1085.  
  1086.   // comparison
  1087.   inline MPI2CPP_BOOL_T operator==(const Errhandler &a);
  1088.  
  1089.   inline MPI2CPP_BOOL_T operator!=(const Errhandler &a) {
  1090.     return (MPI2CPP_BOOL_T)!(*this == a); }
  1091.  
  1092.   // inter-language operability
  1093.   inline Errhandler& operator= (const MPI_Errhandler &i) {
  1094.     mpi_errhandler = i; return *this; }
  1095.  
  1096.   inline operator MPI_Errhandler() const { return mpi_errhandler; }
  1097.  
  1098.   inline operator MPI_Errhandler*() { return &mpi_errhandler; }
  1099.   
  1100.   //
  1101.   // Errhandler access functions
  1102.   //
  1103.   
  1104.   inline virtual void Free(void);
  1105.  
  1106.   Comm::PMPI_Errhandler_fn* handler_fn;
  1107.  
  1108. protected:
  1109.   MPI_Errhandler mpi_errhandler;
  1110.  
  1111. public:
  1112.   //this is for ERRORS_THROW_EXCEPTIONS
  1113.   //this is called from MPI::Real_init
  1114.   // g++ doesn't understand friends so this must be public :(
  1115.   inline void init() const {
  1116.     (void)MPI_Errhandler_create(&throw_excptn_fctn,
  1117.                 (MPI_Errhandler *)&mpi_errhandler); 
  1118.   }
  1119. };
  1120. /* process-header: end of perrhandler.h */
  1121. /* process-header: including pintracomm.h */
  1122.  
  1123. class Intracomm : public Comm {
  1124.  
  1125. #if 0 // friends cause portability problems
  1126. #if _MPIPP_USENAMESPACE_
  1127.   friend void ::op_intercept(void *invec, void *outvec, int *len, MPI_Datatype *datatype);
  1128. #endif
  1129.  
  1130. #if ! _MPIPP_USENAMESPACE_
  1131.   friend void op_intercept(void *invec, void *outvec, int *len, MPI_Datatype *datatype);
  1132. #endif
  1133. #endif
  1134.  
  1135. public:
  1136.   // construction
  1137.   Intracomm() { }
  1138.   // copy
  1139.   Intracomm(const Intracomm& data) : Comm(data) { }
  1140.   
  1141.   // inter-language operability
  1142.   inline Intracomm(const MPI_Comm& data);
  1143.  
  1144.   //
  1145.   // Collective Communication
  1146.   //
  1147.  
  1148.   virtual void Barrier() const;
  1149.  
  1150.   virtual void Bcast(void *buffer, int count, 
  1151.              const Datatype& datatype, int root) const;
  1152.  
  1153.   virtual void Gather(const void *sendbuf, int sendcount, 
  1154.                 const Datatype & sendtype, 
  1155.                 void *recvbuf, int recvcount, 
  1156.                 const Datatype & recvtype, int root) const;
  1157.   
  1158.   virtual void Gatherv(const void *sendbuf, int sendcount, 
  1159.                   const Datatype & sendtype, void *recvbuf, 
  1160.                   const int recvcounts[], const int displs[], 
  1161.                   const Datatype & recvtype, int root) const;
  1162.  
  1163.   virtual void Scatter(const void *sendbuf, int sendcount, 
  1164.                   const Datatype & sendtype, 
  1165.                   void *recvbuf, int recvcount, 
  1166.                   const Datatype & recvtype, int root) const;
  1167.  
  1168.   virtual void Scatterv(const void *sendbuf, const int sendcounts[], 
  1169.                    const int displs[], const Datatype & sendtype,
  1170.                    void *recvbuf, int recvcount, 
  1171.                    const Datatype & recvtype, int root) const;
  1172.  
  1173.   virtual void Allgather(const void *sendbuf, int sendcount, 
  1174.              const Datatype & sendtype, void *recvbuf, 
  1175.              int recvcount, const Datatype & recvtype) const;
  1176.  
  1177.   virtual void Allgatherv(const void *sendbuf, int sendcount, 
  1178.               const Datatype & sendtype, void *recvbuf, 
  1179.               const int recvcounts[], const int displs[],
  1180.               const Datatype & recvtype) const;
  1181.  
  1182.   virtual void Alltoall(const void *sendbuf, int sendcount, 
  1183.             const Datatype & sendtype, void *recvbuf, 
  1184.             int recvcount, const Datatype & recvtype) const;
  1185.  
  1186.   virtual void Alltoallv(const void *sendbuf, const int sendcounts[], 
  1187.              const int sdispls[], const Datatype & sendtype, 
  1188.              void *recvbuf, const int recvcounts[], 
  1189.              const int rdispls[], const Datatype & recvtype) const;
  1190.  
  1191.   virtual void Reduce(const void *sendbuf, void *recvbuf, int count, 
  1192.               const Datatype & datatype, const Op & op, 
  1193.               int root) const;
  1194.  
  1195.   virtual void Allreduce(const void *sendbuf, void *recvbuf, int count,
  1196.                 const Datatype & datatype, const Op & op) const;
  1197.  
  1198.   virtual void Reduce_scatter(const void *sendbuf, void *recvbuf, 
  1199.                      int recvcounts[], 
  1200.                      const Datatype & datatype, 
  1201.                      const Op & op) const;
  1202.  
  1203.   virtual void Scan(const void *sendbuf, void *recvbuf, int count, 
  1204.             const Datatype & datatype, const Op & op) const;
  1205.  
  1206.   Intracomm Dup() const;
  1207.  
  1208. #if VIRTUAL_FUNC_RET
  1209.   Intracomm&
  1210. #else
  1211.   Comm&
  1212. #endif
  1213.   Clone() const;
  1214.  
  1215.   virtual Intracomm Create(const Group& group) const;
  1216.   
  1217.   virtual Intracomm Split(int color, int key) const;
  1218.  
  1219.   virtual Intercomm Create_intercomm(int local_leader, const Comm& peer_comm,
  1220.                       int remote_leader, int tag) const;
  1221.   
  1222.   virtual Cartcomm Create_cart(int ndims, const int dims[],
  1223.                     const MPI2CPP_BOOL_T periods[], MPI2CPP_BOOL_T reorder) const;
  1224.   
  1225.   virtual Graphcomm Create_graph(int nnodes, const int index[],
  1226.                       const int edges[], MPI2CPP_BOOL_T reorder) const;
  1227.  
  1228.  
  1229. protected:
  1230.  
  1231. public: // JGS, friends issue
  1232.   static Op* current_op;
  1233.  
  1234. };
  1235. /* process-header: end of pintracomm.h */
  1236. /* process-header: including ptopology.h */
  1237.  
  1238.  
  1239. class Cartcomm : public Intracomm {
  1240. public:
  1241.    // construction
  1242.   Cartcomm() : Intracomm(MPI_COMM_NULL) { }
  1243.   // copy
  1244.   Cartcomm(const Cartcomm& data) : Intracomm(data) { }
  1245.   // inter-language operability
  1246.   inline Cartcomm(const MPI_Comm& data);
  1247.  
  1248.   //
  1249.   // Groups, Contexts, and Communicators
  1250.   //
  1251.  
  1252.   Cartcomm Dup() const;
  1253.  
  1254. #if VIRTUAL_FUNC_RET
  1255.   Cartcomm&
  1256. #else
  1257.   Comm&
  1258. #endif
  1259.   Clone() const;
  1260.  
  1261.   //
  1262.   //  Process Topologies
  1263.   //
  1264.  
  1265.   virtual int Get_dim() const;
  1266.  
  1267.   // JGS KCC gives a warning here because of Comm::Get_topo()
  1268.   virtual void Get_topo(int maxdims, int dims[], MPI2CPP_BOOL_T periods[],
  1269.                   int coords[]) const;
  1270.  
  1271.   virtual int Get_cart_rank(const int coords[]) const;
  1272.   
  1273.   virtual void Get_coords(int rank, int maxdims, int coords[]) const;
  1274.  
  1275.   virtual void Shift(int direction, int disp,
  1276.              int &rank_source, int &rank_dest) const;
  1277.   
  1278.   virtual Cartcomm Sub(const MPI2CPP_BOOL_T remain_dims[]);
  1279.  
  1280.   virtual int Map(int ndims, const int dims[], const MPI2CPP_BOOL_T periods[]) const;
  1281.  
  1282. };
  1283.  
  1284. //===================================================================
  1285. //                    Class Graphcomm
  1286. //===================================================================
  1287.  
  1288. class Graphcomm : public Intracomm {
  1289. public:
  1290.   // construction
  1291.   Graphcomm() : Intracomm(MPI_COMM_NULL) { }
  1292.   // copy
  1293.   Graphcomm(const Graphcomm& data) : Intracomm(data) { }
  1294.   // inter-language operability
  1295.   inline Graphcomm(const MPI_Comm& data);
  1296.  
  1297.   //
  1298.   // Groups, Contexts, and Communicators
  1299.   //
  1300.  
  1301.   Graphcomm Dup() const;
  1302.  
  1303. #if VIRTUAL_FUNC_RET
  1304.   Graphcomm&
  1305. #else
  1306.   Comm&
  1307. #endif
  1308.   Clone() const;
  1309.  
  1310.   //
  1311.   //  Process Topologies
  1312.   //
  1313.  
  1314.   virtual void Get_dims(int nnodes[], int nedges[]) const;
  1315.  
  1316.   virtual void Get_topo(int maxindex, int maxedges, int index[], 
  1317.             int edges[]) const;
  1318.  
  1319.   virtual int Get_neighbors_count(int rank) const;
  1320.  
  1321.   virtual void Get_neighbors(int rank, int maxneighbors, 
  1322.                  int neighbors[]) const;
  1323.  
  1324.   virtual int Map(int nnodes, const int index[], 
  1325.           const int edges[]) const;
  1326.  
  1327. };
  1328. /* process-header: end of ptopology.h */
  1329. /* process-header: including pintercomm.h */
  1330.  
  1331.  
  1332. class Intercomm : public Comm {
  1333. public:
  1334.  
  1335.   // construction
  1336.   Intercomm() : Comm(MPI_COMM_NULL) { }
  1337.   // copy
  1338.   Intercomm(const Intercomm& data) : Comm(data) { }
  1339.   // inter-language operability
  1340.   Intercomm(const MPI_Comm& data) : Comm(data) { }
  1341.  
  1342.   //
  1343.   // Groups, Contexts, and Communicators
  1344.   //
  1345.  
  1346.   Intercomm Dup() const;
  1347.  
  1348. #if VIRTUAL_FUNC_RET
  1349.   Intercomm&
  1350. #else
  1351.   Comm&
  1352. #endif
  1353.   Clone() const;
  1354.  
  1355.   virtual int Get_remote_size() const;
  1356.  
  1357.   Group Get_remote_group() const;
  1358.   
  1359.   virtual Intracomm Merge(MPI2CPP_BOOL_T high);
  1360.  
  1361. };
  1362. /* process-header: end of pintercomm.h */
  1363.   
  1364. #if ! _MPIPP_USENAMESPACE_
  1365. private:
  1366.   PMPI() { }
  1367. #endif
  1368. };
  1369.  
  1370.  
  1371. #endif
  1372. /* process-header: end of pmpi++.h */
  1373. #endif
  1374.  
  1375. #if _MPIPP_USENAMESPACE_
  1376. namespace MPI {
  1377. #else
  1378. class MPI {
  1379. public:
  1380. #endif
  1381.  
  1382. #if ! _MPIPP_USEEXCEPTIONS_
  1383.   _MPIPP_EXTERN_ _MPIPP_STATIC_ int errno;
  1384. #endif
  1385.  
  1386.   class Comm_Null;
  1387.   class Comm;
  1388.   class Intracomm;
  1389.   class Intercomm;
  1390.   class Graphcomm;
  1391.   class Cartcomm;
  1392.   class Datatype;
  1393.   class Errhandler;
  1394.   class Group;
  1395.   class Op;
  1396.   class Request;
  1397.   class Status;
  1398.  
  1399.   typedef MPI_Aint Aint;
  1400.  
  1401. /* process-header: including constants.h */
  1402.  
  1403.  
  1404. // return  codes
  1405. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int SUCCESS;
  1406. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_BUFFER;
  1407. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_COUNT;
  1408. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_TYPE;
  1409. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_TAG ;
  1410. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_COMM;
  1411. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_RANK;
  1412. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_REQUEST;
  1413. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_ROOT;
  1414. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_GROUP;
  1415. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_OP;
  1416. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_TOPOLOGY;
  1417. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_DIMS;
  1418. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_ARG;
  1419. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_UNKNOWN;
  1420. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_TRUNCATE;
  1421. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_OTHER;
  1422. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_INTERN;
  1423. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_PENDING;
  1424. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_IN_STATUS;
  1425. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ERR_LASTCODE;
  1426.  
  1427. // assorted constants
  1428. _MPIPP_EXTERN_ _MPIPP_STATIC_ const void* BOTTOM;
  1429. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int PROC_NULL;
  1430. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ANY_SOURCE;
  1431. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int ANY_TAG;
  1432. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int UNDEFINED;
  1433. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int BSEND_OVERHEAD;
  1434. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int KEYVAL_INVALID;
  1435.  
  1436. // error-handling specifiers
  1437. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Errhandler  ERRORS_ARE_FATAL;
  1438. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Errhandler  ERRORS_RETURN;
  1439. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Errhandler  ERRORS_THROW_EXCEPTIONS;
  1440.  
  1441. // maximum sizes for strings
  1442. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int MAX_PROCESSOR_NAME;
  1443. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int MAX_ERROR_STRING;
  1444.  
  1445. // elementary datatypes (C / C++)
  1446. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype CHAR;
  1447. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype SHORT;          
  1448. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype INT;            
  1449. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype LONG;
  1450. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype SIGNED_CHAR;
  1451. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype UNSIGNED_CHAR;
  1452. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype UNSIGNED_SHORT; 
  1453. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype UNSIGNED;       
  1454. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype UNSIGNED_LONG;  
  1455. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype FLOAT;
  1456. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype DOUBLE;
  1457. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype LONG_DOUBLE;
  1458. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype BYTE;
  1459. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype PACKED;
  1460.  
  1461. // datatypes for reductions functions (C / C++)
  1462. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype FLOAT_INT;
  1463. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype DOUBLE_INT;
  1464. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype LONG_INT;
  1465. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype TWOINT;
  1466. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype SHORT_INT;
  1467. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype LONG_DOUBLE_INT;
  1468.  
  1469. #if MPI2CPP_FORTRAN
  1470. // elementary datatype (Fortran)
  1471. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype INTEGER;
  1472. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype REAL;
  1473. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype DOUBLE_PRECISION;
  1474. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype F_COMPLEX;
  1475. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype LOGICAL;
  1476. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype CHARACTER;
  1477.  
  1478. // datatype for reduction functions (Fortran)
  1479. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype TWOREAL;
  1480. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype TWODOUBLE_PRECISION;
  1481. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype TWOINTEGER;
  1482. #endif
  1483.  
  1484. #if MPI2CPP_ALL_OPTIONAL_FORTRAN
  1485. // optional datatypes (Fortran)
  1486. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype INTEGER1;
  1487. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype INTEGER2;
  1488. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype INTEGER4;
  1489. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype REAL2;
  1490. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype REAL4;
  1491. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype REAL8;
  1492. #elif MPI2CPP_SOME_OPTIONAL_FORTRAN
  1493. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype INTEGER2;
  1494. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype REAL2;
  1495. #endif
  1496.  
  1497. #if MPI2CPP_OPTIONAL_C
  1498. // optional datatype (C / C++)
  1499. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype LONG_LONG;
  1500. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype UNSIGNED_LONG_LONG;
  1501. #endif
  1502.  
  1503. #if 0
  1504. // c++ types
  1505. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype BOOL;
  1506. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype COMPLEX;
  1507. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype DOUBLE_COMPLEX;
  1508. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype LONG_DOUBLE_COMPLEX;
  1509. #endif
  1510.  
  1511. // special datatypes for contstruction of derived datatypes
  1512. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype UB;
  1513. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype LB;
  1514.  
  1515. // reserved communicators
  1516. // JGS these can not be const because Set_errhandler is not const
  1517. _MPIPP_EXTERN_ _MPIPP_STATIC_ Intracomm COMM_WORLD;
  1518. _MPIPP_EXTERN_ _MPIPP_STATIC_ Intracomm COMM_SELF;
  1519.  
  1520. // results of communicator and group comparisons
  1521. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int IDENT;
  1522. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int CONGRUENT;
  1523. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int SIMILAR;
  1524. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int UNEQUAL;
  1525.  
  1526. // environmental inquiry keys
  1527. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int TAG_UB;
  1528. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int IO;
  1529. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int HOST;
  1530. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int WTIME_IS_GLOBAL;
  1531.  
  1532. // collective operations
  1533. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op MAX;
  1534. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op MIN;
  1535. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op SUM;
  1536. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op PROD;
  1537. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op MAXLOC;
  1538. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op MINLOC;
  1539. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op BAND;
  1540. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op BOR;
  1541. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op BXOR;
  1542. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op LAND;
  1543. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op LOR;
  1544. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op LXOR;
  1545.  
  1546. // null handles
  1547. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Group        GROUP_NULL;
  1548. //_MPIPP_EXTERN_ _MPIPP_STATIC_ const Comm         COMM_NULL;
  1549. //_MPIPP_EXTERN_ _MPIPP_STATIC_ const MPI_Comm     COMM_NULL;
  1550. _MPIPP_EXTERN_ _MPIPP_STATIC_ Comm_Null          COMM_NULL;
  1551. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Datatype     DATATYPE_NULL;
  1552. _MPIPP_EXTERN_ _MPIPP_STATIC_ Request            REQUEST_NULL;
  1553. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Op           OP_NULL;
  1554. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Errhandler   ERRHANDLER_NULL;  
  1555.  
  1556. // empty group
  1557. _MPIPP_EXTERN_ _MPIPP_STATIC_ const Group  GROUP_EMPTY;
  1558.  
  1559. // topologies
  1560. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int GRAPH;
  1561. _MPIPP_EXTERN_ _MPIPP_STATIC_ const int CART;
  1562.  
  1563.  
  1564. /* process-header: end of constants.h */
  1565. /* process-header: including functions.h */
  1566.  
  1567. //
  1568. // Point-to-Point Communication
  1569. //
  1570.  
  1571. _MPIPP_STATIC_ void 
  1572. Attach_buffer(void* buffer, int size);
  1573.  
  1574. _MPIPP_STATIC_ int 
  1575. Detach_buffer(void*& buffer);
  1576.  
  1577. //
  1578. // Process Topologies
  1579. //
  1580.  
  1581. _MPIPP_STATIC_ void
  1582. Compute_dims(int nnodes, int ndims, int dims[]);
  1583.  
  1584. //
  1585. // Environmental Inquiry
  1586. //
  1587.  
  1588. _MPIPP_STATIC_ void 
  1589. Get_processor_name(char*& name, int& resultlen);
  1590.  
  1591. _MPIPP_STATIC_ void
  1592. Get_error_string(int errorcode, char*& string, int& resultlen);
  1593.  
  1594. _MPIPP_STATIC_ int 
  1595. Get_error_class(int errorcode);
  1596.  
  1597. _MPIPP_STATIC_ double 
  1598. Wtime();
  1599.  
  1600. _MPIPP_STATIC_ double 
  1601. Wtick();
  1602.  
  1603. _MPIPP_STATIC_ void
  1604. Init(int& argc, char**& argv);
  1605.  
  1606. _MPIPP_STATIC_ void
  1607. Init();
  1608.  
  1609. _MPIPP_STATIC_ void
  1610. Real_init();
  1611.  
  1612. _MPIPP_STATIC_ void
  1613. Finalize();
  1614.  
  1615. _MPIPP_STATIC_ MPI2CPP_BOOL_T
  1616. Is_initialized();
  1617.  
  1618. //
  1619. // Profiling
  1620. //
  1621.  
  1622. _MPIPP_STATIC_ void
  1623. Pcontrol(const int level, ...);
  1624.  
  1625.  
  1626. // JGS defer to MPI-2
  1627. //inline _MPIPP_STATIC_ void
  1628. //Get_version(int& version, int& subversion);
  1629.  
  1630. _MPIPP_STATIC_ _REAL_MPI_::Aint
  1631. Get_address(void* location);
  1632. /* process-header: end of functions.h */
  1633. /* process-header: including datatype.h */
  1634.  
  1635.  
  1636. class Datatype {
  1637. #if _MPIPP_PROFILING_
  1638.   //  friend class PMPI::Datatype;
  1639. #endif
  1640. public:
  1641.  
  1642. #if _MPIPP_PROFILING_
  1643.  
  1644.   // construction
  1645.   inline Datatype() { }
  1646.  
  1647.   // inter-language operability
  1648.   inline Datatype(const MPI_Datatype &i) : pmpi_datatype(i) { }
  1649.  
  1650.   // copy / assignment
  1651.   inline Datatype(const Datatype& dt) : pmpi_datatype(dt.pmpi_datatype) { }
  1652.  
  1653.   inline Datatype(const PMPI::Datatype& dt) : pmpi_datatype(dt) { }
  1654.   
  1655.   inline virtual ~Datatype() {}
  1656.  
  1657.   inline Datatype& operator=(const Datatype& dt) {
  1658.     pmpi_datatype = dt.pmpi_datatype; return *this; }
  1659.  
  1660.   // comparison
  1661.   inline MPI2CPP_BOOL_T operator== (const Datatype &a) const
  1662.     { return (MPI2CPP_BOOL_T) (pmpi_datatype == a); }
  1663.  
  1664.   inline MPI2CPP_BOOL_T operator!= (const Datatype &a) const
  1665.     { return (MPI2CPP_BOOL_T) !(*this == a); }
  1666.  
  1667.   // inter-language operability
  1668.   inline Datatype& operator= (const MPI_Datatype &i) 
  1669.     { pmpi_datatype = i; return *this; }
  1670.  
  1671.   inline operator MPI_Datatype() const { return (MPI_Datatype)pmpi_datatype; }
  1672.   //  inline operator MPI_Datatype* ()/* JGS const */ { return pmpi_datatype; }
  1673.  
  1674.   inline operator const PMPI::Datatype&() const { return pmpi_datatype; }
  1675.  
  1676.   inline const PMPI::Datatype& pmpi() const { return pmpi_datatype; }
  1677.  
  1678. #else
  1679.  
  1680.   // construction / destruction
  1681.   inline Datatype() : mpi_datatype(MPI_DATATYPE_NULL) { }
  1682.   inline virtual ~Datatype() {}
  1683.   // inter-language operability
  1684.   inline Datatype(const MPI_Datatype &i) : mpi_datatype(i) { }
  1685.  
  1686.   // copy / assignment
  1687.   inline Datatype(const Datatype& dt) : mpi_datatype(dt.mpi_datatype) { }
  1688.   inline Datatype& operator=(const Datatype& dt) {
  1689.     mpi_datatype = dt.mpi_datatype; return *this; }
  1690.  
  1691.   // comparison
  1692.   inline MPI2CPP_BOOL_T operator== (const Datatype &a) const
  1693.     { return (MPI2CPP_BOOL_T) (mpi_datatype == a.mpi_datatype); }
  1694.  
  1695.   inline MPI2CPP_BOOL_T operator!= (const Datatype &a) const
  1696.     { return (MPI2CPP_BOOL_T) !(*this == a); }
  1697.  
  1698.   // inter-language operability
  1699.   inline Datatype& operator= (const MPI_Datatype &i) 
  1700.     { mpi_datatype = i; return *this; }
  1701.  
  1702.   inline operator MPI_Datatype () const { return mpi_datatype; }
  1703.   // inline operator MPI_Datatype* ()/* JGS const */ { return &mpi_datatype; }
  1704.  
  1705. #endif
  1706.   
  1707.   //
  1708.   // Point-to-Point Communication
  1709.   //
  1710.   
  1711.   virtual Datatype Create_contiguous(int count) const;
  1712.   
  1713.   virtual Datatype Create_vector(int count, int blocklength,
  1714.                  int stride) const;
  1715.   
  1716.   virtual Datatype Create_indexed(int count,
  1717.                   const int array_of_blocklengths[], 
  1718.                   const int array_of_displacements[]) const;
  1719.  
  1720.   static Datatype Create_struct(int count, const int array_of_blocklengths[],
  1721.                 const Aint array_of_displacements[],
  1722.                 const Datatype array_if_types[]);
  1723.   
  1724.   virtual Datatype Create_hindexed(int count, const int array_of_blocklengths[],
  1725.                    const Aint array_of_displacements[]) const;
  1726.  
  1727.   virtual Datatype Create_hvector(int count, int blocklength, Aint stride) const;
  1728.  
  1729.   virtual int Get_size() const;
  1730.   
  1731.   virtual void Get_extent(Aint& lb, Aint& extent) const;
  1732.  
  1733.   virtual void Commit();
  1734.   
  1735.   virtual void Free();
  1736.  
  1737.   virtual void Pack(const void* inbuf, int incount, void *outbuf, 
  1738.             int outsize, int& position, const Comm &comm) const;
  1739.  
  1740.   virtual void Unpack(const void* inbuf, int insize, void *outbuf, int outcount,
  1741.               int& position, const Comm& comm) const;
  1742.  
  1743.   virtual int Pack_size(int incount, const Comm& comm) const;
  1744.  
  1745. #if _MPIPP_PROFILING_
  1746. private:
  1747.   PMPI::Datatype pmpi_datatype;
  1748. #else
  1749. protected:
  1750.   MPI_Datatype mpi_datatype;
  1751. #endif
  1752.  
  1753.  
  1754. };
  1755.  
  1756. /* process-header: end of datatype.h */
  1757.  
  1758.   typedef void User_function(const void* invec, void* inoutvec, int len,
  1759.                  const Datatype& datatype);
  1760.  
  1761. /* process-header: including exception.h */
  1762.  
  1763.  
  1764. class Exception {
  1765. public:
  1766.  
  1767. #if _MPIPP_PROFILING_
  1768.  
  1769.   inline Exception(int ec) : pmpi_exception(ec) { }
  1770.  
  1771.   int Get_error_code() const;
  1772.   
  1773.   int Get_error_class() const;
  1774.   
  1775.   const char* Get_error_string() const;
  1776.  
  1777. #else
  1778.  
  1779.   inline Exception(int ec) : error_code(ec) {
  1780.     (void)MPI_Error_class(error_code, &error_class);
  1781.     int resultlen;
  1782.     error_string = new char[MAX_ERROR_STRING];
  1783.     (void)MPI_Error_string(error_code, error_string, &resultlen);
  1784.   }
  1785.  
  1786.   inline int Get_error_code() const { return error_code; }
  1787.  
  1788.   inline int Get_error_class() const { return error_class; }
  1789.   
  1790.   inline const char* Get_error_string() const { return error_string; }
  1791.  
  1792. #endif
  1793.  
  1794. protected:
  1795. #if _MPIPP_PROFILING_
  1796.   PMPI::Exception pmpi_exception;
  1797. #else
  1798.   int error_code;
  1799.   char* error_string;
  1800.   int error_class;
  1801. #endif
  1802. };
  1803. /* process-header: end of exception.h */
  1804. /* process-header: including op.h */
  1805.  
  1806.  
  1807. class Op {
  1808. #if _MPIPP_PROFILING_
  1809.   //  friend class PMPI::Op;
  1810. #endif
  1811. public:
  1812.  
  1813.   // construction
  1814.   Op();
  1815.   Op(const MPI_Op &i);
  1816.   Op(const Op& op);
  1817. #if _MPIPP_PROFILING_
  1818.   Op(const PMPI::Op& op) : pmpi_op(op) { }
  1819. #endif
  1820.   // destruction
  1821.   virtual ~Op();
  1822.   // assignment
  1823.   Op& operator=(const Op& op);
  1824.   Op& operator= (const MPI_Op &i);
  1825.   // comparison
  1826.   inline MPI2CPP_BOOL_T operator== (const Op &a);
  1827.   inline MPI2CPP_BOOL_T operator!= (const Op &a);
  1828.   // conversion functions for inter-language operability
  1829.   inline operator MPI_Op () const;
  1830.   //  inline operator MPI_Op* (); //JGS const
  1831. #if _MPIPP_PROFILING_
  1832.   inline operator const PMPI::Op&() const { return pmpi_op; }
  1833. #endif
  1834.   // Collective Communication
  1835.   //JGS took const out
  1836.   virtual void Init(User_function *func, MPI2CPP_BOOL_T commute);
  1837.   virtual void Free();
  1838.  
  1839. #if ! _MPIPP_PROFILING_
  1840.   User_function *op_user_function; //JGS move to private
  1841. protected:
  1842.   MPI_Op mpi_op;
  1843. #endif
  1844.  
  1845. #if _MPIPP_PROFILING_
  1846. private:
  1847.   PMPI::Op pmpi_op;
  1848. #endif
  1849.  
  1850. };
  1851.  
  1852. /* process-header: end of op.h */
  1853. /* process-header: including status.h */
  1854.  
  1855.  
  1856. class Status {
  1857. #if _MPIPP_PROFILING_
  1858.   //  friend class PMPI::Status;
  1859. #endif
  1860.   friend class MPI::Comm; //so I can access pmpi_status data member in comm.cc
  1861.   friend class MPI::Request; //and also from request.cc
  1862.  
  1863. public:
  1864. #if _MPIPP_PROFILING_
  1865.  
  1866.   // construction / destruction
  1867.   Status() { }
  1868.   virtual ~Status() {}
  1869.  
  1870.   // copy / assignment
  1871.   Status(const Status& data) : pmpi_status(data.pmpi_status) { }
  1872.  
  1873.   Status(const MPI_Status &i) : pmpi_status(i) { }
  1874.  
  1875.   Status& operator=(const Status& data) {
  1876.     pmpi_status = data.pmpi_status; return *this; }
  1877.  
  1878.   // comparison, don't need for status
  1879.  
  1880.   // inter-language operability
  1881.   Status& operator= (const MPI_Status &i) {
  1882.     pmpi_status = i; return *this; }
  1883.   operator MPI_Status () const { return pmpi_status; }
  1884.   //  operator MPI_Status* () const { return pmpi_status; }
  1885.   operator const PMPI::Status&() const { return pmpi_status; }
  1886.  
  1887. #else
  1888.  
  1889.   Status() { }
  1890.   // copy
  1891.   Status(const Status& data) : mpi_status(data.mpi_status) { }
  1892.  
  1893.   Status(const MPI_Status &i) : mpi_status(i) { }
  1894.  
  1895.   virtual ~Status() {}
  1896.  
  1897.   Status& operator=(const Status& data) {
  1898.     mpi_status = data.mpi_status; return *this; }
  1899.  
  1900.   // comparison, don't need for status
  1901.  
  1902.   // inter-language operability
  1903.   Status& operator= (const MPI_Status &i) {
  1904.     mpi_status = i; return *this; }
  1905.   operator MPI_Status () const { return mpi_status; }
  1906.   //  operator MPI_Status* () const { return (MPI_Status*)&mpi_status; }
  1907.  
  1908. #endif
  1909.  
  1910.   //
  1911.   // Point-to-Point Communication
  1912.   //
  1913.  
  1914.   virtual int Get_count(const Datatype& datatype) const;
  1915.  
  1916.   virtual MPI2CPP_BOOL_T Is_cancelled() const;
  1917.  
  1918.   virtual int Get_elements(const Datatype& datatype) const;
  1919.  
  1920.   //
  1921.   // Status Access
  1922.   //
  1923.   virtual int Get_source() const;
  1924.  
  1925.   virtual void Set_source(int source);
  1926.  
  1927.   virtual int Get_tag() const;
  1928.   
  1929.   virtual void Set_tag(int tag);
  1930.   
  1931.   virtual int Get_error() const;
  1932.  
  1933.   virtual void Set_error(int error);
  1934.  
  1935. protected:
  1936. #if _MPIPP_PROFILING_
  1937.   PMPI::Status pmpi_status;
  1938. #else
  1939.   MPI_Status mpi_status;
  1940. #endif
  1941.  
  1942. };
  1943. /* process-header: end of status.h */
  1944. /* process-header: including request.h */
  1945.  
  1946.  
  1947. class Request {
  1948. #if _MPIPP_PROFILING_
  1949.   //    friend class PMPI::Request;
  1950. #endif
  1951. public:
  1952. #if _MPIPP_PROFILING_
  1953.  
  1954.   // construction
  1955.   Request() { }
  1956.   Request(const MPI_Request &i) : pmpi_request(i) { }
  1957.  
  1958.   // copy / assignment
  1959.   Request(const Request& r) : pmpi_request(r.pmpi_request) { }
  1960.  
  1961.   Request(const PMPI::Request& r) : pmpi_request(r) { }
  1962.  
  1963.   virtual ~Request() {}
  1964.  
  1965.   Request& operator=(const Request& r) {
  1966.     pmpi_request = r.pmpi_request; return *this; }
  1967.  
  1968.   // comparison
  1969.   MPI2CPP_BOOL_T operator== (const Request &a) 
  1970.   { return (MPI2CPP_BOOL_T)(pmpi_request == a); }
  1971.   MPI2CPP_BOOL_T operator!= (const Request &a) 
  1972.   { return (MPI2CPP_BOOL_T)!(*this == a); }
  1973.  
  1974.   // inter-language operability
  1975.   Request& operator= (const MPI_Request &i) {
  1976.     pmpi_request = i; return *this;  }
  1977.  
  1978.   operator MPI_Request () const { return pmpi_request; }
  1979.   //  operator MPI_Request* () const { return pmpi_request; }
  1980.   operator const PMPI::Request&() const { return pmpi_request; }
  1981.  
  1982. #else
  1983.  
  1984.   // construction / destruction
  1985.   Request() { mpi_request = MPI_REQUEST_NULL; }
  1986.   virtual ~Request() {}
  1987.   Request(const MPI_Request &i) : mpi_request(i) { }
  1988.  
  1989.   // copy / assignment
  1990.   Request(const Request& r) : mpi_request(r.mpi_request) { }
  1991.  
  1992.   Request& operator=(const Request& r) {
  1993.     mpi_request = r.mpi_request; return *this; }
  1994.  
  1995.   // comparison
  1996.   MPI2CPP_BOOL_T operator== (const Request &a) 
  1997.   { return (MPI2CPP_BOOL_T)(mpi_request == a.mpi_request); }
  1998.   MPI2CPP_BOOL_T operator!= (const Request &a) 
  1999.   { return (MPI2CPP_BOOL_T)!(*this == a); }
  2000.  
  2001.   // inter-language operability
  2002.   Request& operator= (const MPI_Request &i) {
  2003.     mpi_request = i; return *this; }
  2004.   operator MPI_Request () const { return mpi_request; }
  2005.   //  operator MPI_Request* () const { return (MPI_Request*)&mpi_request; }
  2006.  
  2007. #endif
  2008.  
  2009.   //
  2010.   // Point-to-Point Communication
  2011.   //
  2012.  
  2013.   virtual void Wait(Status &status);
  2014.  
  2015.   virtual void Wait();
  2016.  
  2017.   virtual MPI2CPP_BOOL_T Test(Status &status);
  2018.  
  2019.   virtual MPI2CPP_BOOL_T Test();
  2020.  
  2021.   virtual void Free(void);
  2022.  
  2023.   static int Waitany(int count, Request array[], Status& status);
  2024.  
  2025.   static int Waitany(int count, Request array[]);
  2026.  
  2027.   static MPI2CPP_BOOL_T Testany(int count, Request array[], int& index, Status& status);
  2028.  
  2029.   static MPI2CPP_BOOL_T Testany(int count, Request array[], int& index);
  2030.  
  2031.   static void Waitall(int count, Request req_array[], Status stat_array[]);
  2032.  
  2033.   static void Waitall(int count, Request req_array[]);
  2034.  
  2035.   static MPI2CPP_BOOL_T Testall(int count, Request req_array[], Status stat_array[]);
  2036.  
  2037.   static MPI2CPP_BOOL_T Testall(int count, Request req_array[]);
  2038.  
  2039.   static int Waitsome(int incount, Request req_array[],
  2040.                  int array_of_indices[], Status stat_array[]) ;
  2041.  
  2042.   static int Waitsome(int incount, Request req_array[],
  2043.                  int array_of_indices[]);
  2044.  
  2045.   static int Testsome(int incount, Request req_array[],
  2046.                  int array_of_indices[], Status stat_array[]);
  2047.  
  2048.   static int Testsome(int incount, Request req_array[],
  2049.                  int array_of_indices[]);
  2050.  
  2051.   virtual void Cancel(void) const;
  2052.  
  2053.  
  2054. protected:
  2055. #if ! _MPIPP_PROFILING_
  2056.   MPI_Request mpi_request;
  2057. #endif
  2058.  
  2059. private:
  2060.   static Status ignored_status;
  2061.  
  2062. #if _MPIPP_PROFILING_
  2063.   PMPI::Request pmpi_request;
  2064. #endif 
  2065.  
  2066. };
  2067.  
  2068.  
  2069. class Prequest : public Request {
  2070. #if _MPIPP_PROFILING_
  2071.   //  friend class PMPI::Prequest;
  2072. #endif
  2073. public:
  2074.  
  2075.   Prequest() { }
  2076.  
  2077. #if _MPIPP_PROFILING_
  2078.   Prequest(const Request& p) : pmpi_request(p), Request(p) { }
  2079.  
  2080.   Prequest(const PMPI::Prequest& r) : pmpi_request(r), Request((const PMPI::Request&)r) { }
  2081.  
  2082.   Prequest(const MPI_Request &i) : pmpi_request(i), Request(i) { }
  2083.   
  2084.   virtual ~Prequest() { }
  2085.  
  2086.   Prequest& operator=(const Request& r) {
  2087.     Request::operator=(r);
  2088.     pmpi_request = (PMPI::Prequest)r; return *this; }
  2089.  
  2090.   Prequest& operator=(const Prequest& r) {
  2091.     Request::operator=(r);
  2092.     pmpi_request = r.pmpi_request; return *this; }
  2093. #else
  2094.   Prequest(const Request& p) : Request(p) { }
  2095.  
  2096.   Prequest(const MPI_Request &i) : Request(i) { }
  2097.  
  2098.   virtual ~Prequest() { }
  2099.  
  2100.   Prequest& operator=(const Request& r) {
  2101.     mpi_request = r; return *this; }
  2102.  
  2103.   Prequest& operator=(const Prequest& r) {
  2104.     mpi_request = r.mpi_request; return *this; }
  2105. #endif
  2106.  
  2107.   virtual void Start();
  2108.  
  2109.   static void Startall(int count, Prequest array_of_requests[]);
  2110.  
  2111. #if _MPIPP_PROFILING_
  2112. private:
  2113.   PMPI::Prequest pmpi_request;
  2114. #endif 
  2115. };
  2116. /* process-header: end of request.h */
  2117. /* process-header: including group.h */
  2118.  
  2119. class Group {
  2120. #if _MPIPP_PROFILING_
  2121.   //  friend class PMPI::Group;
  2122. #endif
  2123. public:
  2124.  
  2125. #if _MPIPP_PROFILING_
  2126.  
  2127.   // construction
  2128.   inline Group() { }
  2129.   inline Group(const MPI_Group &i) : pmpi_group(i) { }
  2130.   // copy
  2131.   inline Group(const Group& g) : pmpi_group(g.pmpi_group) { }
  2132.  
  2133.   inline Group(const PMPI::Group& g) : pmpi_group(g) { }
  2134.  
  2135.   inline virtual ~Group() {}
  2136.  
  2137.   Group& operator=(const Group& g) {
  2138.     pmpi_group = g.pmpi_group; return *this;
  2139.   }
  2140.  
  2141.   // comparison
  2142.   inline MPI2CPP_BOOL_T operator== (const Group &a) {
  2143.     return (MPI2CPP_BOOL_T)(pmpi_group == a);
  2144.   }
  2145.   inline MPI2CPP_BOOL_T operator!= (const Group &a) { 
  2146.     return (MPI2CPP_BOOL_T)!(*this == a);
  2147.   }
  2148.  
  2149.   // inter-language operability
  2150.   Group& operator= (const MPI_Group &i) { pmpi_group = i; return *this; }
  2151.   inline operator MPI_Group () const { return pmpi_group.mpi(); }
  2152.   //  inline operator MPI_Group* () const { return pmpi_group; }
  2153.   inline operator const PMPI::Group&() const { return pmpi_group; }
  2154.  
  2155.   const PMPI::Group& pmpi() { return pmpi_group; }
  2156. #else
  2157.  
  2158.   // construction
  2159.   inline Group() : mpi_group(MPI_GROUP_NULL) { }
  2160.   inline Group(const MPI_Group &i) : mpi_group(i) { }
  2161.  
  2162.   // copy
  2163.   inline Group(const Group& g) : mpi_group(g.mpi_group) { }
  2164.  
  2165.   inline virtual ~Group() {}
  2166.  
  2167.   inline Group& operator=(const Group& g) { mpi_group = g.mpi_group; return *this; }
  2168.  
  2169.   // comparison
  2170.   inline MPI2CPP_BOOL_T operator== (const Group &a) { return (MPI2CPP_BOOL_T)(mpi_group == a.mpi_group); }
  2171.   inline MPI2CPP_BOOL_T operator!= (const Group &a) { return (MPI2CPP_BOOL_T)!(*this == a); }
  2172.  
  2173.   // inter-language operability
  2174.   inline Group& operator= (const MPI_Group &i) { mpi_group = i; return *this; }
  2175.   inline operator MPI_Group () const { return mpi_group; }
  2176.   //  inline operator MPI_Group* () const { return (MPI_Group*)&mpi_group; }
  2177.  
  2178.   inline MPI_Group mpi() const { return mpi_group; }
  2179.  
  2180. #endif
  2181.  
  2182.   //
  2183.   // Groups, Contexts, and Communicators
  2184.   //
  2185.  
  2186.   virtual int Get_size() const;
  2187.   
  2188.   virtual int Get_rank() const;
  2189.   
  2190.   static void Translate_ranks (const Group& group1, int n, const int ranks1[], 
  2191.                    const Group& group2, int ranks2[]);
  2192.   
  2193.   static int Compare(const Group& group1, const Group& group2);
  2194.   
  2195.   static Group Union(const Group &group1, const Group &group2);
  2196.   
  2197.   static Group Intersect(const Group &group1, const Group &group2);
  2198.   
  2199.   static Group Difference(const Group &group1, const Group &group2);
  2200.   
  2201.   virtual Group Incl(int n, const int ranks[]) const;
  2202.   
  2203.   virtual Group Excl(int n, const int ranks[]) const;
  2204.   
  2205.   virtual Group Range_incl(int n, const int ranges[][3]) const;
  2206.   
  2207.   virtual Group Range_excl(int n, const int ranges[][3]) const;
  2208.   
  2209.   virtual void Free();
  2210.  
  2211. protected:
  2212. #if ! _MPIPP_PROFILING_
  2213.   MPI_Group mpi_group;
  2214. #endif
  2215.  
  2216. #if _MPIPP_PROFILING_
  2217. private:
  2218.   PMPI::Group pmpi_group;
  2219. #endif
  2220.  
  2221. };
  2222.  
  2223. /* process-header: end of group.h */
  2224. /* process-header: including comm.h */
  2225.  
  2226. #define COMM_NOT_ABSTRACT 1
  2227.  
  2228. class Comm_Null {
  2229. #if _MPIPP_PROFILING_
  2230.   //  friend class PMPI::Comm_Null;
  2231. #endif
  2232. public:
  2233.  
  2234. #if _MPIPP_PROFILING_
  2235.  
  2236.   // construction
  2237.   inline Comm_Null() { }
  2238.   // copy
  2239.   inline Comm_Null(const Comm_Null& data) : pmpi_comm(data.pmpi_comm) { }
  2240.   // inter-language operability  
  2241.   inline Comm_Null(const MPI_Comm& data) : pmpi_comm(data) { }
  2242.  
  2243.   inline Comm_Null(const PMPI::Comm_Null& data) : pmpi_comm(data) { }
  2244.  
  2245.   // destruction
  2246.   //JGS  virtual inline ~Comm_Null() { }
  2247.  
  2248.   inline Comm_Null& operator=(const Comm_Null& data) {
  2249.     pmpi_comm = data.pmpi_comm; 
  2250.     return *this;
  2251.   }
  2252.  
  2253.   // comparison
  2254.   inline MPI2CPP_BOOL_T operator==(const Comm_Null& data) const {
  2255.     return (MPI2CPP_BOOL_T) (pmpi_comm == data.pmpi_comm); }
  2256.  
  2257.   inline MPI2CPP_BOOL_T operator!=(const Comm_Null& data) const {
  2258.     return (MPI2CPP_BOOL_T) (pmpi_comm != data.pmpi_comm);}
  2259.  
  2260.   // inter-language operability (conversion operators)
  2261.   inline operator MPI_Comm() const { return pmpi_comm; }
  2262.   //  inline operator MPI_Comm*() /*const JGS*/ { return pmpi_comm; }
  2263.   inline operator const PMPI::Comm_Null&() const { return pmpi_comm; }
  2264.  
  2265. #else
  2266.  
  2267.   // construction
  2268.   inline Comm_Null() : mpi_comm(MPI_COMM_NULL) { }
  2269.   // copy
  2270.   inline Comm_Null(const Comm_Null& data) : mpi_comm(data.mpi_comm) { }
  2271.   // inter-language operability  
  2272.   inline Comm_Null(const MPI_Comm& data) : mpi_comm(data) { }
  2273.  
  2274.   // destruction
  2275.   //JGS virtual inline ~Comm_Null() { }
  2276.  
  2277.  // comparison
  2278.   // JGS make sure this is right (in other classes too)
  2279.   inline MPI2CPP_BOOL_T operator==(const Comm_Null& data) const {
  2280.     return (MPI2CPP_BOOL_T) (mpi_comm == data.mpi_comm); }
  2281.  
  2282.   inline MPI2CPP_BOOL_T operator!=(const Comm_Null& data) const {
  2283.     return (MPI2CPP_BOOL_T) !(*this == data);}
  2284.  
  2285.   // inter-language operability (conversion operators)
  2286.   inline operator MPI_Comm() const { return mpi_comm; }
  2287.  
  2288. #endif
  2289.  
  2290.   
  2291. protected:
  2292.  
  2293. #if _MPIPP_PROFILING_
  2294.   PMPI::Comm_Null pmpi_comm;
  2295. #else
  2296.   MPI_Comm mpi_comm;
  2297. #endif
  2298.   
  2299.  
  2300. };
  2301.  
  2302.  
  2303. class Comm : public Comm_Null {
  2304. #if _MPIPP_PROFILING_
  2305.   //  friend class PMPI::Comm;
  2306. #else
  2307.  
  2308.  
  2309. #if 0
  2310.   // JGS, screw it. Between the friend differences, the
  2311.   // function differences, and the :: problem with egcs
  2312.   // this is not worth it. I'm just going to make the stuff
  2313.   // these functions need public
  2314.  
  2315. #if _MPIPP_USENAMESPACE_
  2316.   //JGS, when using namespaces, the :: are required. For some strange
  2317.   //reason they are not for nested classes.
  2318.  
  2319. #if MPI2CPP_IBM_SP
  2320.   friend void ::errhandler_intercept(MPI_Comm * mpi_comm, int * err, char*, int*, int*);
  2321. #else
  2322.   friend void ::errhandler_intercept(MPI_Comm * mpi_comm, int* err, ...);
  2323. #endif
  2324.   friend int ::copy_attr_intercept(MPI_Comm oldcomm, int keyval, 
  2325.                  void *extra_state, void *attribute_val_in, 
  2326.                  void *attribute_val_out, int *flag);
  2327.   friend int ::delete_attr_intercept(MPI_Comm comm, int keyval, 
  2328.                    void *attribute_val, void *extra_state);
  2329. #endif
  2330.  
  2331. #if ! _MPIPP_USENAMESPACE_
  2332.  
  2333. #if MPI2CPP_IBM_SP
  2334.   friend void errhandler_intercept(MPI_Comm * mpi_comm, int * err, char*, int*, int*);
  2335. #else
  2336.   friend void errhandler_intercept(MPI_Comm * mpi_comm, int* err, ...);
  2337. #endif
  2338.   friend int copy_attr_intercept(MPI_Comm oldcomm, int keyval, 
  2339.                  void *extra_state, void *attribute_val_in, 
  2340.                  void *attribute_val_out, int *flag);
  2341.   friend int delete_attr_intercept(MPI_Comm comm, int keyval, 
  2342.                    void *attribute_val, void *extra_state);
  2343. #endif
  2344.  
  2345. #endif
  2346.  
  2347. #endif
  2348.  
  2349. public:
  2350.  
  2351.   typedef void Errhandler_fn(Comm&, int*, ...);
  2352.   typedef int Copy_attr_function(const Comm& oldcomm, int comm_keyval,
  2353.                  void* extra_state, void* attribute_val_in,
  2354.                  void* attribute_val_out, MPI2CPP_BOOL_T& flag);
  2355.   typedef int Delete_attr_function(Comm& comm, int comm_keyval, void* attribute_val,
  2356.                    void* extra_state);
  2357. #if !_MPIPP_PROFILING_
  2358. #define ERRHANDLERFN Errhandler_fn
  2359. #define COPYATTRFN Copy_attr_function
  2360. #define DELETEATTRFN Delete_attr_function
  2361. #endif
  2362.  
  2363.   // construction
  2364.   Comm() { }
  2365.  
  2366.   // copy
  2367.   Comm(const Comm_Null& data) : Comm_Null(data) { }
  2368.  
  2369. #if _MPIPP_PROFILING_
  2370.   Comm(const Comm& data) : Comm_Null(data) { }
  2371.  
  2372.   // inter-language operability
  2373.   Comm(const MPI_Comm& data) : pmpi_comm(data), Comm_Null(data) { }
  2374.  
  2375.   Comm(const PMPI::Comm& data) : pmpi_comm(data), Comm_Null((const PMPI::Comm_Null&)data) { }
  2376.  
  2377.   operator const PMPI::Comm&() const { return pmpi_comm; }
  2378.  
  2379.   // assignment
  2380.   Comm& operator=(const Comm& data) {
  2381.     this->Comm_Null::operator=(data);
  2382.     pmpi_comm = data.pmpi_comm; 
  2383.     return *this;
  2384.   }
  2385.   Comm& operator=(const Comm_Null& data) {
  2386.     this->Comm_Null::operator=(data);
  2387.     MPI_Comm tmp = data;
  2388.     pmpi_comm = tmp; 
  2389.     return *this;
  2390.   }
  2391.   // inter-language operability
  2392.   Comm& operator=(const MPI_Comm& data) {
  2393.     this->Comm_Null::operator=(data);
  2394.     pmpi_comm = data;
  2395.     return *this;
  2396.   }
  2397.  
  2398. #else
  2399.   Comm(const Comm& data) : Comm_Null(data.mpi_comm) { }
  2400.   // inter-language operability
  2401.   Comm(const MPI_Comm& data) : Comm_Null(data) { }
  2402. #endif
  2403.  
  2404.  
  2405.   //
  2406.   // Point-to-Point
  2407.   //
  2408.  
  2409.   virtual void Send(const void *buf, int count, 
  2410.             const Datatype & datatype, int dest, int tag) const;
  2411.  
  2412.   virtual void Recv(void *buf, int count, const Datatype & datatype,
  2413.             int source, int tag, Status & status) const;
  2414.  
  2415.  
  2416.   virtual void Recv(void *buf, int count, const Datatype & datatype,
  2417.             int source, int tag) const;
  2418.   
  2419.   virtual void Bsend(const void *buf, int count,
  2420.              const Datatype & datatype, int dest, int tag) const;
  2421.   
  2422.   virtual void Ssend(const void *buf, int count, 
  2423.                const Datatype & datatype, int dest, int tag) const ;
  2424.  
  2425.   virtual void Rsend(const void *buf, int count,
  2426.              const Datatype & datatype, int dest, int tag) const;
  2427.   
  2428.   virtual Request Isend(const void *buf, int count,
  2429.             const Datatype & datatype, int dest, int tag) const;
  2430.   
  2431.   virtual Request Ibsend(const void *buf, int count, const
  2432.              Datatype & datatype, int dest, int tag) const;
  2433.   
  2434.   virtual Request Issend(const void *buf, int count,
  2435.              const Datatype & datatype, int dest, int tag) const;
  2436.   
  2437.   virtual Request Irsend(const void *buf, int count,
  2438.              const Datatype & datatype, int dest, int tag) const;
  2439.  
  2440.   virtual Request Irecv(void *buf, int count,
  2441.             const Datatype & datatype, int source, int tag) const;
  2442.  
  2443.   virtual MPI2CPP_BOOL_T Iprobe(int source, int tag, Status & status) const;
  2444.  
  2445.   virtual MPI2CPP_BOOL_T Iprobe(int source, int tag) const;
  2446.  
  2447.   virtual void Probe(int source, int tag, Status & status) const;
  2448.   
  2449.   virtual void Probe(int source, int tag) const;
  2450.   
  2451.   virtual Prequest Send_init(const void *buf, int count,
  2452.                  const Datatype & datatype, int dest, int tag) const;
  2453.   
  2454.   virtual Prequest Bsend_init(const void *buf, int count,
  2455.                   const Datatype & datatype, int dest, int tag) const;
  2456.   
  2457.   virtual Prequest Ssend_init(const void *buf, int count,
  2458.                   const Datatype & datatype, int dest, int tag) const;
  2459.   
  2460.   virtual Prequest Rsend_init(const void *buf, int count,
  2461.                   const Datatype & datatype, int dest, int tag) const;
  2462.   
  2463.   virtual Prequest Recv_init(void *buf, int count,
  2464.                  const Datatype & datatype, int source, int tag) const;
  2465.   
  2466.   virtual void Sendrecv(const void *sendbuf, int sendcount,
  2467.             const Datatype & sendtype, int dest, int sendtag, 
  2468.             void *recvbuf, int recvcount, 
  2469.             const Datatype & recvtype, int source,
  2470.             int recvtag, Status & status) const;
  2471.   
  2472.   virtual void Sendrecv(const void *sendbuf, int sendcount,
  2473.             const Datatype & sendtype, int dest, int sendtag, 
  2474.             void *recvbuf, int recvcount, 
  2475.             const Datatype & recvtype, int source,
  2476.             int recvtag) const;
  2477.  
  2478.   virtual void Sendrecv_replace(void *buf, int count,
  2479.                 const Datatype & datatype, int dest, 
  2480.                 int sendtag, int source,
  2481.                 int recvtag, Status & status) const;
  2482.  
  2483.   virtual void Sendrecv_replace(void *buf, int count,
  2484.                 const Datatype & datatype, int dest, 
  2485.                 int sendtag, int source,
  2486.                 int recvtag) const;
  2487.   
  2488.   //
  2489.   // Groups, Contexts, and Communicators
  2490.   //
  2491.  
  2492.   virtual Group Get_group() const;
  2493.   
  2494.   virtual int Get_size() const;
  2495.  
  2496.   virtual int Get_rank() const;
  2497.   
  2498.   static int Compare(const Comm & comm1, const Comm & comm2);
  2499.   
  2500.   virtual Comm& Clone() const = 0;
  2501.  
  2502.   virtual void Free(void);
  2503.   
  2504.   virtual MPI2CPP_BOOL_T Is_inter() const;
  2505.   
  2506.   //
  2507.   //Process Topologies
  2508.   //
  2509.   
  2510.   virtual int Get_topology() const;
  2511.   
  2512.   //
  2513.   // Environmental Inquiry
  2514.   //
  2515.   
  2516.   virtual void Abort(int errorcode);
  2517.  
  2518.   //
  2519.   // Errhandler
  2520.   //
  2521.  
  2522.   virtual void Set_errhandler(const Errhandler& errhandler);
  2523.  
  2524.   virtual Errhandler Get_errhandler() const;
  2525.  
  2526.   //JGS took out const below from fn arg
  2527.   static Errhandler Create_errhandler(Comm::Errhandler_fn* function);
  2528.  
  2529.   //
  2530.   // Keys and Attributes
  2531.   //
  2532.  
  2533. //JGS I took the const out because it causes problems when trying to
  2534. //call this function with the predefined NULL_COPY_FN etc.
  2535.   static int Create_keyval(Copy_attr_function* comm_copy_attr_fn,
  2536.                Delete_attr_function* comm_delete_attr_fn,
  2537.                void* extra_state);
  2538.   
  2539.   static void Free_keyval(int& comm_keyval);
  2540.  
  2541.   virtual void Set_attr(int comm_keyval, const void* attribute_val) const;
  2542.  
  2543.   virtual MPI2CPP_BOOL_T Get_attr(int comm_keyval, void* attribute_val) const;
  2544.   
  2545.   virtual void Delete_attr(int comm_keyval);
  2546.  
  2547.   static int NULL_COPY_FN(const Comm& oldcomm, int comm_keyval,
  2548.               void* extra_state, void* attribute_val_in,
  2549.               void* attribute_val_out, MPI2CPP_BOOL_T& flag);
  2550.   
  2551.   static int DUP_FN(const Comm& oldcomm, int comm_keyval,
  2552.             void* extra_state, void* attribute_val_in,
  2553.             void* attribute_val_out, MPI2CPP_BOOL_T& flag);
  2554.   
  2555.   static int NULL_DELETE_FN(Comm& comm, int comm_keyval, void* attribute_val,
  2556.                 void* extra_state);
  2557.  
  2558.  
  2559.   //#if _MPIPP_PROFILING_
  2560.   //  virtual const PMPI::Comm& get_pmpi_comm() const { return pmpi_comm; }
  2561.   //#endif
  2562.  
  2563. private:
  2564. #if _MPIPP_PROFILING_
  2565.   PMPI::Comm pmpi_comm;
  2566. #endif
  2567.  
  2568.   static Status ignored_status;
  2569.  
  2570. #if ! _MPIPP_PROFILING_
  2571. public: // JGS hmmm, these used by errhandler_intercept
  2572.         // should make it a friend
  2573.   static MPI_SGI_Map mpi_comm_map;
  2574.   Errhandler* my_errhandler;
  2575.   static MPI_SGI_Map key_fn_map;
  2576.  
  2577.   void init() {
  2578.     my_errhandler = (Errhandler*)0;
  2579.   }
  2580. #endif
  2581.  
  2582. };
  2583.  
  2584.  
  2585.  
  2586. /* process-header: end of comm.h */
  2587. /* process-header: including errhandler.h */
  2588.  
  2589. class Errhandler {
  2590. #if 0 // JGS compilers hate friends :(
  2591. #if _MPIPP_USENAMESPACE_
  2592.   friend void _REAL_MPI_::Real_init();  //see function init below
  2593. #else
  2594.   friend class _REAL_MPI_; //g++ won't except above friend function
  2595. #endif
  2596. #endif
  2597.  
  2598. public:
  2599.  
  2600. #if _MPIPP_PROFILING_
  2601.  
  2602.   // construction / destruction
  2603.   inline Errhandler() { }
  2604.  
  2605.   inline virtual ~Errhandler() {}
  2606.  
  2607.   inline Errhandler(const MPI_Errhandler &i)
  2608.     : pmpi_errhandler(i) { }
  2609.  
  2610.  // copy / assignment
  2611.   inline Errhandler(const Errhandler& e)
  2612.     : pmpi_errhandler(e.pmpi_errhandler) { }
  2613.  
  2614.   inline Errhandler(const PMPI::Errhandler& e)
  2615.     : pmpi_errhandler(e) { }
  2616.  
  2617.   inline Errhandler& operator=(const Errhandler& e) {
  2618.     pmpi_errhandler = e.pmpi_errhandler; return *this; }
  2619.  
  2620.   // comparison
  2621.   inline MPI2CPP_BOOL_T operator==(const Errhandler &a) {
  2622.     return (MPI2CPP_BOOL_T)(pmpi_errhandler == a); }
  2623.   
  2624.   inline MPI2CPP_BOOL_T operator!=(const Errhandler &a) {
  2625.     return (MPI2CPP_BOOL_T)!(*this == a); }
  2626.  
  2627.   // inter-language operability
  2628.   inline Errhandler& operator= (const MPI_Errhandler &i) {
  2629.     pmpi_errhandler = i; return *this; }
  2630.  
  2631.   inline operator MPI_Errhandler() const { return pmpi_errhandler; }
  2632.  
  2633.   //  inline operator MPI_Errhandler*() { return pmpi_errhandler; }
  2634.   
  2635.   inline operator const PMPI::Errhandler&() const { return pmpi_errhandler; }
  2636.  
  2637. #else
  2638.  
  2639.   // construction / destruction
  2640.   inline Errhandler()
  2641.     : mpi_errhandler(MPI_ERRHANDLER_NULL) {}
  2642.  
  2643.   inline virtual ~Errhandler() {}
  2644.  
  2645.   inline Errhandler(const MPI_Errhandler &i)
  2646.     : mpi_errhandler(i) {}
  2647.  
  2648.  // copy / assignment
  2649.   inline Errhandler(const Errhandler& e)
  2650.     : handler_fn(e.handler_fn), mpi_errhandler(e.mpi_errhandler) { }
  2651.  
  2652.   inline Errhandler& operator=(const Errhandler& e)
  2653.   {
  2654.     mpi_errhandler = e.mpi_errhandler;
  2655.     handler_fn = e.handler_fn;
  2656.     return *this;
  2657.   }
  2658.  
  2659.   // comparison
  2660.   inline MPI2CPP_BOOL_T operator==(const Errhandler &a) {
  2661.     return (MPI2CPP_BOOL_T)(mpi_errhandler == a.mpi_errhandler); }
  2662.   
  2663.   inline MPI2CPP_BOOL_T operator!=(const Errhandler &a) {
  2664.     return (MPI2CPP_BOOL_T)!(*this == a); }
  2665.  
  2666.   // inter-language operability
  2667.   inline Errhandler& operator= (const MPI_Errhandler &i) {
  2668.     mpi_errhandler = i; return *this; }
  2669.  
  2670.   inline operator MPI_Errhandler() const { return mpi_errhandler; }
  2671.  
  2672.   //  inline operator MPI_Errhandler*() { return &mpi_errhandler; }
  2673.   
  2674. #endif
  2675.  
  2676.   //
  2677.   // Errhandler access functions
  2678.   //
  2679.   
  2680.   virtual void Free();
  2681.  
  2682. #if !_MPIPP_PROFILING_
  2683.   Comm::Errhandler_fn* handler_fn;
  2684. #endif
  2685.  
  2686. protected:
  2687. #if _MPIPP_PROFILING_
  2688.   PMPI::Errhandler pmpi_errhandler;
  2689. #else
  2690.   MPI_Errhandler mpi_errhandler;
  2691. #endif
  2692.  
  2693.  
  2694. public:
  2695.   // took out the friend decls
  2696.   //private:
  2697.  
  2698.   //this is for ERRORS_THROW_EXCEPTIONS
  2699.   //this is called from MPI::Real_init
  2700.   inline void init() const {
  2701. #if ! _MPIPP_PROFILING_
  2702.     (void)MPI_Errhandler_create(&throw_excptn_fctn,
  2703.                 (MPI_Errhandler *)&mpi_errhandler); 
  2704. #else
  2705.     pmpi_errhandler.init();
  2706. #endif
  2707.   }
  2708.  
  2709. };
  2710.  
  2711.  
  2712. /* process-header: end of errhandler.h */
  2713. /* process-header: including intracomm.h */
  2714.  
  2715. class Intracomm : public Comm {
  2716.  
  2717. #if 0
  2718.   // JGS to many portability issues with these friend decls (see comm.h)
  2719.   // going to just make some stuff public
  2720. #if ! _MPIPP_PROFILING_
  2721. #if _MPIPP_USENAMESPACE_
  2722.   friend void ::op_intercept(void *invec, void *outvec, int *len, MPI_Datatype *datatype);
  2723. #endif
  2724.  
  2725. #if ! _MPIPP_USENAMESPACE_
  2726.   friend void op_intercept(void *invec, void *outvec, int *len, MPI_Datatype *datatype);
  2727. #endif
  2728.  
  2729. #endif // #if ! _MPIPP_PROFILING_
  2730.  
  2731. #endif // #if 0
  2732.  
  2733. public:
  2734.  
  2735.   // construction
  2736.   Intracomm() { }
  2737.   // copy
  2738.   Intracomm(const Comm_Null& data) : Comm(data) { }
  2739.   // inter-language operability
  2740.  
  2741. #if _MPIPP_PROFILING_
  2742.   Intracomm(const Intracomm& data) : Comm(data) { }
  2743.  
  2744.   //NOTE: it is extremely important that Comm(data) happens below
  2745.   //  because there is a not only pmpi_comm in this Intracomm but
  2746.   //  there is also a pmpi_comm in the inherited Comm part. Both
  2747.   //  of these pmpi_comm's need to be initialized with the same
  2748.   //  MPI_Comm object. Also the assignment operators must take this
  2749.   //  into account.
  2750.   Intracomm(const MPI_Comm& data) : pmpi_comm(data), Comm(data) { }
  2751.   
  2752.   Intracomm(const PMPI::Intracomm& data) : pmpi_comm(data), Comm((const PMPI::Comm&)data) { }
  2753.  
  2754.   // assignment
  2755.   Intracomm& operator=(const Intracomm& data) {
  2756.     Comm::operator=(data);
  2757.     pmpi_comm = data.pmpi_comm; 
  2758.     return *this;
  2759.   }
  2760.   Intracomm& operator=(const Comm_Null& data) {
  2761.     Comm::operator=(data);
  2762.     pmpi_comm = (PMPI::Intracomm)data; return *this;
  2763.   }
  2764.   // inter-language operability
  2765.   Intracomm& operator=(const MPI_Comm& data) {
  2766.     Comm::operator=(data);
  2767.     pmpi_comm = data;
  2768.     return *this;
  2769.   }
  2770.  
  2771. #else
  2772.   Intracomm(const Intracomm& data) : Comm(data.mpi_comm) { }
  2773.  
  2774.   inline Intracomm(const MPI_Comm& data);
  2775.  
  2776.   // assignment
  2777.   Intracomm& operator=(const Intracomm& data) {
  2778.     mpi_comm = data.mpi_comm; return *this;
  2779.   }
  2780.  
  2781.   Intracomm& operator=(const Comm_Null& data) {
  2782.     mpi_comm = data; return *this;
  2783.   }
  2784.  
  2785.   // inter-language operability
  2786.   Intracomm& operator=(const MPI_Comm& data) {
  2787.     mpi_comm = data; return *this; } 
  2788.  
  2789. #endif
  2790.  
  2791.   //
  2792.   // Collective Communication
  2793.   //
  2794.  
  2795.   virtual void
  2796.   Barrier() const;
  2797.  
  2798.   virtual void
  2799.   Bcast(void *buffer, int count, 
  2800.     const Datatype& datatype, int root) const;
  2801.   
  2802.   virtual void
  2803.   Gather(const void *sendbuf, int sendcount, 
  2804.      const Datatype & sendtype, 
  2805.      void *recvbuf, int recvcount, 
  2806.      const Datatype & recvtype, int root) const;
  2807.   
  2808.   virtual void
  2809.   Gatherv(const void *sendbuf, int sendcount, 
  2810.       const Datatype & sendtype, void *recvbuf, 
  2811.       const int recvcounts[], const int displs[], 
  2812.       const Datatype & recvtype, int root) const;
  2813.   
  2814.   virtual void
  2815.   Scatter(const void *sendbuf, int sendcount, 
  2816.       const Datatype & sendtype, 
  2817.       void *recvbuf, int recvcount, 
  2818.       const Datatype & recvtype, int root) const;
  2819.   
  2820.   virtual void
  2821.   Scatterv(const void *sendbuf, const int sendcounts[], 
  2822.        const int displs[], const Datatype & sendtype,
  2823.        void *recvbuf, int recvcount, 
  2824.        const Datatype & recvtype, int root) const;
  2825.   
  2826.   virtual void
  2827.   Allgather(const void *sendbuf, int sendcount, 
  2828.         const Datatype & sendtype, void *recvbuf, 
  2829.         int recvcount, const Datatype & recvtype) const;
  2830.   
  2831.   virtual void
  2832.   Allgatherv(const void *sendbuf, int sendcount, 
  2833.          const Datatype & sendtype, void *recvbuf, 
  2834.          const int recvcounts[], const int displs[],
  2835.          const Datatype & recvtype) const;
  2836.   
  2837.   virtual void
  2838.   Alltoall(const void *sendbuf, int sendcount, 
  2839.        const Datatype & sendtype, void *recvbuf, 
  2840.        int recvcount, const Datatype & recvtype) const;
  2841.   
  2842.   virtual void
  2843.   Alltoallv(const void *sendbuf, const int sendcounts[], 
  2844.         const int sdispls[], const Datatype & sendtype, 
  2845.         void *recvbuf, const int recvcounts[], 
  2846.         const int rdispls[], const Datatype & recvtype) const;
  2847.   
  2848.   virtual void
  2849.   Reduce(const void *sendbuf, void *recvbuf, int count, 
  2850.      const Datatype & datatype, const Op & op, 
  2851.      int root) const;
  2852.   
  2853.   
  2854.   virtual void
  2855.   Allreduce(const void *sendbuf, void *recvbuf, int count,
  2856.         const Datatype & datatype, const Op & op) const;
  2857.   
  2858.   virtual void
  2859.   Reduce_scatter(const void *sendbuf, void *recvbuf, 
  2860.          int recvcounts[], 
  2861.          const Datatype & datatype, 
  2862.          const Op & op) const;
  2863.   
  2864.   virtual void
  2865.   Scan(const void *sendbuf, void *recvbuf, int count, 
  2866.        const Datatype & datatype, const Op & op) const;
  2867.   
  2868.   Intracomm
  2869.   Dup() const;
  2870.   
  2871.  
  2872.   virtual
  2873. #if VIRTUAL_FUNC_RET
  2874.   Intracomm&
  2875. #else
  2876.   Comm&
  2877. #endif
  2878.   Clone() const;
  2879.  
  2880.   virtual Intracomm
  2881.   Create(const Group& group) const;
  2882.   
  2883.   virtual Intracomm
  2884.   Split(int color, int key) const;
  2885.  
  2886.   virtual Intercomm
  2887.   Create_intercomm(int local_leader, const Comm& peer_comm,
  2888.            int remote_leader, int tag) const;
  2889.   
  2890.   virtual Cartcomm
  2891.   Create_cart(int ndims, const int dims[],
  2892.           const MPI2CPP_BOOL_T periods[], MPI2CPP_BOOL_T reorder) const;
  2893.   
  2894.   virtual Graphcomm
  2895.   Create_graph(int nnodes, const int index[],
  2896.            const int edges[], MPI2CPP_BOOL_T reorder) const;
  2897.  
  2898.   //#if _MPIPP_PROFILING_
  2899.   //  virtual const PMPI::Comm& get_pmpi_comm() const { return pmpi_comm; }
  2900.   //#endif
  2901. protected:
  2902.  
  2903.  
  2904. #if _MPIPP_PROFILING_
  2905.   PMPI::Intracomm pmpi_comm;
  2906. #endif
  2907.  
  2908. public: // JGS see above about friend decls
  2909. #if ! _MPIPP_PROFILING_
  2910.   static Op* current_op;
  2911. #endif
  2912.  
  2913. };
  2914. /* process-header: end of intracomm.h */
  2915. /* process-header: including topology.h */
  2916.  
  2917.  
  2918. class Cartcomm : public Intracomm {
  2919. public:
  2920.  
  2921.   // construction
  2922.   Cartcomm() { }
  2923.   // copy
  2924.   Cartcomm(const Comm_Null& data) : Intracomm(data) { }
  2925.   // inter-language operability
  2926.   inline Cartcomm(const MPI_Comm& data);
  2927. #if _MPIPP_PROFILING_
  2928.   Cartcomm(const Cartcomm& data) : Intracomm(data) { }
  2929.   Cartcomm(const PMPI::Cartcomm& d) : pmpi_comm(d), Intracomm((const PMPI::Intracomm&)d) { }
  2930.   
  2931.   // assignment
  2932.   Cartcomm& operator=(const Cartcomm& data) {
  2933.     Intracomm::operator=(data);
  2934.     pmpi_comm = data.pmpi_comm; return *this; }
  2935.   Cartcomm& operator=(const Comm_Null& data) {
  2936.     Intracomm::operator=(data);
  2937.     pmpi_comm = (PMPI::Cartcomm)data; return *this; }
  2938.   // inter-language operability
  2939.   Cartcomm& operator=(const MPI_Comm& data) {
  2940.     Intracomm::operator=(data);
  2941.     pmpi_comm = data; return *this; }
  2942. #else
  2943.   Cartcomm(const Cartcomm& data) : Intracomm(data.mpi_comm) { }
  2944.   // assignment
  2945.   Cartcomm& operator=(const Cartcomm& data) {
  2946.     mpi_comm = data.mpi_comm; return *this; }
  2947.   Cartcomm& operator=(const Comm_Null& data) {
  2948.     mpi_comm = data; return *this; }
  2949.   // inter-language operability
  2950.   Cartcomm& operator=(const MPI_Comm& data) {
  2951.     mpi_comm = data; return *this; } 
  2952. #endif
  2953.   //
  2954.   // Groups, Contexts, and Communicators
  2955.   //
  2956.  
  2957.   Cartcomm Dup() const;
  2958.  
  2959.   virtual
  2960. #if VIRTUAL_FUNC_RET
  2961.   Cartcomm&
  2962. #else
  2963.   Comm&
  2964. #endif
  2965.   Clone() const;
  2966.  
  2967.  
  2968.   //
  2969.   // Groups, Contexts, and Communicators
  2970.   //
  2971.  
  2972.   virtual int Get_dim() const;
  2973.  
  2974.   virtual void Get_topo(int maxdims, int dims[], MPI2CPP_BOOL_T periods[],
  2975.             int coords[]) const;
  2976.  
  2977.   virtual int Get_cart_rank(const int coords[]) const;
  2978.  
  2979.   virtual void Get_coords(int rank, int maxdims, int coords[]) const;
  2980.  
  2981.   virtual void Shift(int direction, int disp,
  2982.              int &rank_source, int &rank_dest) const;
  2983.   
  2984.   virtual Cartcomm Sub(const MPI2CPP_BOOL_T remain_dims[]);
  2985.  
  2986.   virtual int Map(int ndims, const int dims[], const MPI2CPP_BOOL_T periods[]) const;
  2987.  
  2988. #if _MPIPP_PROFILING_
  2989. private:
  2990.   PMPI::Cartcomm pmpi_comm;
  2991. #endif
  2992. };
  2993.  
  2994.  
  2995. //===================================================================
  2996. //                    Class Graphcomm
  2997. //===================================================================
  2998.  
  2999. class Graphcomm : public Intracomm {
  3000. public:
  3001.  
  3002.   // construction
  3003.   Graphcomm() { }
  3004.   // copy
  3005.   Graphcomm(const Comm_Null& data) : Intracomm(data) { }
  3006.   // inter-language operability
  3007.   inline Graphcomm(const MPI_Comm& data);
  3008. #if _MPIPP_PROFILING_
  3009.   Graphcomm(const Graphcomm& data) : Intracomm(data) { }
  3010.   Graphcomm(const PMPI::Graphcomm& d) : pmpi_comm(d), Intracomm((const PMPI::Intracomm&)d) { }
  3011.   
  3012.   // assignment
  3013.   Graphcomm& operator=(const Graphcomm& data) {
  3014.     Intracomm::operator=(data);
  3015.     pmpi_comm = data.pmpi_comm; return *this; }
  3016.   Graphcomm& operator=(const Comm_Null& data) {
  3017.     Intracomm::operator=(data);
  3018.     pmpi_comm = (PMPI::Graphcomm)data; return *this; }
  3019.   // inter-language operability
  3020.   Graphcomm& operator=(const MPI_Comm& data) {
  3021.     Intracomm::operator=(data);
  3022.     pmpi_comm = data; return *this; }
  3023.  
  3024. #else
  3025.   Graphcomm(const Graphcomm& data) : Intracomm(data.mpi_comm) { }
  3026.   // assignment
  3027.   Graphcomm& operator=(const Graphcomm& data) {
  3028.     mpi_comm = data.mpi_comm; return *this; }
  3029.   Graphcomm& operator=(const Comm_Null& data) {
  3030.     mpi_comm = data; return *this; }
  3031.   // inter-language operability
  3032.   Graphcomm& operator=(const MPI_Comm& data) {
  3033.     mpi_comm = data; return *this; } 
  3034. #endif
  3035.  
  3036.   //
  3037.   // Groups, Contexts, and Communicators
  3038.   //
  3039.   
  3040.   Graphcomm Dup() const;
  3041.  
  3042.   virtual
  3043. #if VIRTUAL_FUNC_RET  
  3044.   Graphcomm&
  3045. #else
  3046.   Comm&
  3047. #endif
  3048.   Clone() const;
  3049.  
  3050.   //
  3051.   //  Process Topologies
  3052.   //
  3053.  
  3054.   virtual void Get_dims(int nnodes[], int nedges[]) const;
  3055.  
  3056.   virtual void Get_topo(int maxindex, int maxedges, int index[], 
  3057.             int edges[]) const;
  3058.  
  3059.   virtual int Get_neighbors_count(int rank) const;
  3060.  
  3061.   virtual void Get_neighbors(int rank, int maxneighbors, 
  3062.                  int neighbors[]) const;
  3063.  
  3064.   virtual int Map(int nnodes, const int index[], 
  3065.           const int edges[]) const;
  3066.  
  3067. #if _MPIPP_PROFILING_
  3068. private:
  3069.   PMPI::Graphcomm pmpi_comm;
  3070. #endif
  3071. };
  3072.  
  3073. /* process-header: end of topology.h */
  3074. /* process-header: including intercomm.h */
  3075.  
  3076.  
  3077. class Intercomm : public Comm {
  3078. #if _MPIPP_PROFILING_
  3079.   //  friend class PMPI::Intercomm;
  3080. #endif
  3081. public:
  3082.  
  3083.   // construction
  3084.   Intercomm() : Comm(MPI_COMM_NULL) { }
  3085.   // copy
  3086.   Intercomm(const Comm_Null& data) : Comm(data) { }
  3087.   // inter-language operability
  3088.   Intercomm(const MPI_Comm& data) : Comm(data) { }
  3089.  
  3090. #if _MPIPP_PROFILING_
  3091.   // copy
  3092.   Intercomm(const Intercomm& data) : pmpi_comm(data.pmpi_comm), Comm(data) { }
  3093.   Intercomm(const PMPI::Intercomm& d) : pmpi_comm(d), Comm((const PMPI::Comm&)d) { }
  3094.  
  3095.   // assignment
  3096.   Intercomm& operator=(const Intercomm& data) {
  3097.     Comm::operator=(data);
  3098.     pmpi_comm = data.pmpi_comm; return *this; }
  3099.   Intercomm& operator=(const Comm_Null& data) {
  3100.     Comm::operator=(data);
  3101.     Intercomm& ic = (Intercomm&)data;
  3102.     pmpi_comm = ic.pmpi_comm; return *this; }
  3103.   // inter-language operability
  3104.   Intercomm& operator=(const MPI_Comm& data) {
  3105.     Comm::operator=(data);
  3106.     pmpi_comm = PMPI::Intercomm(data); return *this; }
  3107. #else
  3108.   // copy
  3109.   Intercomm(const Intercomm& data) : Comm(data.mpi_comm) { }
  3110.   // assignment
  3111.   Intercomm& operator=(const Intercomm& data) {
  3112.     mpi_comm = data.mpi_comm; return *this; }
  3113.   Intercomm& operator=(const Comm_Null& data) {
  3114.     mpi_comm = data; return *this; }
  3115.   // inter-language operability
  3116.   Intercomm& operator=(const MPI_Comm& data) {
  3117.     mpi_comm = data; return *this; } 
  3118.  
  3119. #endif
  3120.   
  3121.  
  3122.   //
  3123.   // Groups, Contexts, and Communicators
  3124.   //
  3125.  
  3126.   Intercomm Dup() const;
  3127.  
  3128.   virtual
  3129. #if VIRTUAL_FUNC_RET
  3130.   Intercomm&
  3131. #else
  3132.   Comm&
  3133. #endif
  3134.   Clone() const;
  3135.  
  3136.   virtual int Get_remote_size() const;
  3137.  
  3138.   virtual Group Get_remote_group() const;
  3139.  
  3140.   virtual Intracomm Merge(MPI2CPP_BOOL_T high);
  3141.  
  3142.   //#if _MPIPP_PROFILING_
  3143.   //  virtual const PMPI::Comm& get_pmpi_comm() const { return pmpi_comm; }
  3144.   //#endif
  3145.  
  3146. #if _MPIPP_PROFILING_
  3147. private:
  3148.   PMPI::Intercomm pmpi_comm;
  3149. #endif
  3150. };
  3151. /* process-header: end of intercomm.h */
  3152.   
  3153. #if ! _MPIPP_USENAMESPACE_
  3154. private:
  3155.   MPI() { }
  3156. #endif
  3157. };
  3158.  
  3159. #if _MPIPP_PROFILING_
  3160. /* process-header: including pop_inln.h */
  3161.  
  3162. inline PMPI::Op&
  3163. PMPI::Op::operator=(const PMPI::Op& op)
  3164. {
  3165.   mpi_op = op.mpi_op;
  3166.   op_user_function = op.op_user_function;
  3167.   return *this;
  3168.  
  3169. // comparison
  3170. inline MPI2CPP_BOOL_T
  3171. PMPI::Op::operator==(const PMPI::Op &a)
  3172. {
  3173.   return (MPI2CPP_BOOL_T)(mpi_op == a.mpi_op);
  3174. }
  3175.  
  3176. inline MPI2CPP_BOOL_T //this will never be used?
  3177. PMPI::Op::operator!= (const PMPI::Op &a) { return (MPI2CPP_BOOL_T)!(*this == a); }
  3178.  
  3179. // inter-language operability
  3180. inline PMPI::Op&
  3181. PMPI::Op::operator= (const MPI_Op &i) { mpi_op = i; return *this; }
  3182.  
  3183. inline
  3184. PMPI::Op::operator MPI_Op () const { return mpi_op; }
  3185.  
  3186. //inline
  3187. //PMPI::Op::operator MPI_Op* () const { return (MPI_Op*)&mpi_op; }
  3188.  
  3189.  
  3190. /* process-header: end of pop_inln.h */
  3191. /* process-header: including pgroup_inln.h */
  3192.  
  3193.  
  3194.  
  3195. /* process-header: end of pgroup_inln.h */
  3196. /* process-header: including pstatus_inln.h */
  3197. /* process-header: end of pstatus_inln.h */
  3198. /* process-header: including prequest_inln.h */
  3199.  
  3200. /* process-header: end of prequest_inln.h */
  3201. #endif
  3202.  
  3203. //
  3204. // These are the "real" functions, whether prototyping is enabled
  3205. // or not. These functions are assigned to either the MPI::XXX class
  3206. // or the PMPI::XXX class based on the value of the macro _REAL_MPI_
  3207. // which is set in mpi2c++_config.h.
  3208. // If prototyping is enabled, there is a top layer that calls these
  3209. // PMPI functions, and this top layer is in the XXX.cc files.
  3210. //
  3211.  
  3212.  
  3213.  
  3214. /* process-header: including datatype_inln.h */
  3215.  
  3216. //
  3217. // Point-to-Point Communication
  3218. //
  3219.  
  3220. inline _REAL_MPI_::Datatype
  3221. _REAL_MPI_::Datatype::Create_contiguous(int count) const
  3222. {
  3223.   MPI_Datatype newtype;
  3224.   (void)MPI_Type_contiguous(count, mpi_datatype, &newtype);
  3225.   return newtype;
  3226. }
  3227.  
  3228. inline _REAL_MPI_::Datatype
  3229. _REAL_MPI_::Datatype::Create_vector(int count, int blocklength,
  3230.                  int stride) const
  3231. {
  3232.   MPI_Datatype newtype;
  3233.   (void)MPI_Type_vector(count, blocklength, stride, mpi_datatype, &newtype);
  3234.   return newtype;
  3235. }
  3236.  
  3237. inline _REAL_MPI_::Datatype
  3238. _REAL_MPI_::Datatype::Create_indexed(int count,
  3239.                      const int array_of_blocklengths[], 
  3240.                      const int array_of_displacements[]) const
  3241. {
  3242.   MPI_Datatype newtype;
  3243.   (void)MPI_Type_indexed(count, (int *) array_of_blocklengths, 
  3244.              (int *) array_of_displacements, mpi_datatype, &newtype);
  3245.   return newtype;
  3246. }
  3247.  
  3248. // JGS MPI_TYPE_STRUCT soon to be depracated in favor of
  3249. // MPI_TYPE_CREATE_STRUCT
  3250. inline _REAL_MPI_::Datatype
  3251. _REAL_MPI_::Datatype::Create_struct(int count, const int array_of_blocklengths[],
  3252.                     const _REAL_MPI_::Aint array_of_displacements[],
  3253.                     const _REAL_MPI_::Datatype array_of_types[])
  3254. {
  3255.   MPI_Datatype newtype;
  3256.   int i;
  3257.   MPI_Datatype* type_array = new MPI_Datatype[count];
  3258.   for (i=0; i < count; i++)
  3259.     type_array[i] = array_of_types[i];
  3260.  
  3261.   (void)MPI_Type_struct(count, (int*)array_of_blocklengths,
  3262.             (MPI_Aint*)array_of_displacements, type_array, &newtype);
  3263.   delete [] type_array;
  3264.   return newtype;
  3265. }
  3266.  
  3267. //JGS MPI_Type_hindexed to be replaced by MPI_Type_create_hindexed
  3268. inline _REAL_MPI_::Datatype
  3269. _REAL_MPI_::Datatype::Create_hindexed(int count, const int array_of_blocklengths[],
  3270.                       const _REAL_MPI_::Aint array_of_displacements[]) const
  3271. {
  3272.   MPI_Datatype newtype;
  3273.   (void)MPI_Type_hindexed(count, (int*)array_of_blocklengths,
  3274.               (MPI_Aint*)array_of_displacements,
  3275.               mpi_datatype, &newtype) ;
  3276.   return newtype;
  3277. }
  3278.  
  3279. //JGS MPI_Type_hvector to be replaced by MPI_Type_create_hvector
  3280. inline _REAL_MPI_::Datatype
  3281. _REAL_MPI_::Datatype::Create_hvector(int count, int blocklength,
  3282.                      _REAL_MPI_::Aint stride) const
  3283. {
  3284.   MPI_Datatype newtype;
  3285.   (void)MPI_Type_hvector(count, blocklength, (MPI_Aint)stride,
  3286.              mpi_datatype, &newtype);
  3287.  
  3288.   return newtype;
  3289. }
  3290.  
  3291. inline int
  3292. _REAL_MPI_::Datatype::Get_size() const 
  3293. {
  3294.   int size;
  3295.   (void)MPI_Type_size(mpi_datatype, &size);
  3296.   return size;
  3297. }
  3298.  
  3299. inline void
  3300. _REAL_MPI_::Datatype::Get_extent(_REAL_MPI_::Aint& lb, _REAL_MPI_::Aint& extent) const
  3301. {
  3302.   // JGS MPI_TYPE_EXTENT and MPI_LB soon to be deprecated
  3303.   // in favor of MPI_TYPE_GET_EXTENT
  3304.   (void)MPI_Type_lb(mpi_datatype, &lb);
  3305.   (void)MPI_Type_extent(mpi_datatype, &extent); 
  3306. }
  3307.  
  3308. inline void
  3309. _REAL_MPI_::Datatype::Commit() 
  3310. {
  3311.   (void)MPI_Type_commit(&mpi_datatype);
  3312. }
  3313.  
  3314. inline void
  3315. _REAL_MPI_::Datatype::Free()
  3316. {
  3317.   (void)MPI_Type_free(&mpi_datatype);
  3318. }
  3319.  
  3320. inline void
  3321. _REAL_MPI_::Datatype::Pack(const void* inbuf, int incount,
  3322.                void *outbuf, int outsize,
  3323.                int& position, const _REAL_MPI_::Comm &comm) const
  3324. {
  3325.   (void)MPI_Pack((void *) inbuf, incount,  mpi_datatype, outbuf,
  3326.          outsize, &position, comm);
  3327. }
  3328.  
  3329. inline void
  3330. _REAL_MPI_::Datatype::Unpack(const void* inbuf, int insize,
  3331.                  void *outbuf, int outcount, int& position,
  3332.                  const _REAL_MPI_::Comm& comm) const 
  3333. {
  3334.   (void)MPI_Unpack((void *) inbuf, insize, &position,
  3335.            outbuf, outcount, mpi_datatype, comm);
  3336. }
  3337.  
  3338. inline int
  3339. _REAL_MPI_::Datatype::Pack_size(int incount, const _REAL_MPI_::Comm& comm) const 
  3340. {
  3341.   int size;
  3342.   (void)MPI_Pack_size(incount, mpi_datatype, comm, &size);
  3343.   return size;
  3344. }
  3345. /* process-header: end of datatype_inln.h */
  3346. /* process-header: including functions_inln.h */
  3347.  
  3348.  
  3349. //
  3350. // Point-to-Point Communication
  3351. //
  3352.  
  3353. inline void 
  3354. _REAL_MPI_::Attach_buffer(void* buffer, int size)
  3355. {
  3356.   (void)MPI_Buffer_attach(buffer, size);
  3357. }
  3358.  
  3359. inline int 
  3360. _REAL_MPI_::Detach_buffer(void*& buffer)
  3361. {
  3362.   int size;
  3363.   (void)MPI_Buffer_detach(&buffer, &size);
  3364.   return size;
  3365. }
  3366.  
  3367. //
  3368. // Process Topologies
  3369. //
  3370.  
  3371. inline void
  3372. _REAL_MPI_::Compute_dims(int nnodes, int ndims, int dims[])
  3373. {
  3374.   (void)MPI_Dims_create(nnodes, ndims, dims);
  3375. }
  3376.  
  3377.  
  3378. //
  3379. // Environmental Inquiry
  3380. //
  3381.  
  3382. inline void 
  3383. _REAL_MPI_::Get_processor_name(char*& name, int& resultlen)
  3384. {
  3385.   (void)MPI_Get_processor_name(name, &resultlen);
  3386. }
  3387.  
  3388. inline void
  3389. _REAL_MPI_::Get_error_string(int errorcode, char*& string, int& resultlen)
  3390. {
  3391.   (void)MPI_Error_string(errorcode, string, &resultlen);
  3392. }
  3393.  
  3394. inline int 
  3395. _REAL_MPI_::Get_error_class(int errorcode) 
  3396. {
  3397.   int errorclass;
  3398.   (void)MPI_Error_class(errorcode, &errorclass);
  3399.   return errorclass;
  3400. }
  3401.  
  3402. inline double 
  3403. _REAL_MPI_::Wtime()
  3404. {
  3405.   return (MPI_Wtime());
  3406. }
  3407.  
  3408. inline double 
  3409. _REAL_MPI_::Wtick()
  3410. {
  3411.   return (MPI_Wtick());
  3412. }
  3413.  
  3414. inline void
  3415. _REAL_MPI_::Real_init()
  3416. {
  3417.   MPI::ERRORS_THROW_EXCEPTIONS.init();
  3418. }
  3419.  
  3420. inline void
  3421. _REAL_MPI_::Init(int& argc, char**& argv)
  3422. {
  3423.   (void)MPI_Init(&argc, &argv);
  3424.   Real_init();
  3425. }
  3426.  
  3427. inline void
  3428. _REAL_MPI_::Init()
  3429. {
  3430.   (void)MPI_Init(0, 0);
  3431.   Real_init();
  3432. }
  3433.  
  3434. inline void
  3435. _REAL_MPI_::Finalize()
  3436. {
  3437.   (void)MPI_Finalize();
  3438. }
  3439.  
  3440. inline MPI2CPP_BOOL_T
  3441. _REAL_MPI_::Is_initialized()
  3442. {
  3443.   int t;
  3444.   (void)MPI_Initialized(&t);
  3445.   return (MPI2CPP_BOOL_T) t;
  3446. }
  3447.  
  3448. //
  3449. // Profiling
  3450. //
  3451.  
  3452. inline void
  3453. _REAL_MPI_::Pcontrol(const int level, ...)
  3454. {
  3455.   va_list ap;
  3456.   va_start(ap, level);
  3457.  
  3458.   (void)MPI_Pcontrol(level, ap);
  3459.   va_end(ap);
  3460. }
  3461.  
  3462. //JGS, MPI_Address soon to be replaced by MPI_Get_address
  3463. inline _REAL_MPI_::Aint
  3464. _REAL_MPI_::Get_address(void* location)
  3465. {
  3466.   _REAL_MPI_::Aint ret;
  3467.   MPI_Address(location, &ret);
  3468.   return ret;
  3469. }
  3470.  
  3471.  
  3472. /* process-header: end of functions_inln.h */
  3473. /* process-header: including request_inln.h */
  3474.  
  3475. //
  3476. // Point-to-Point Communication
  3477. //
  3478.  
  3479. inline void
  3480. _REAL_MPI_::Request::Wait(_REAL_MPI_::Status &status) 
  3481. {
  3482.   (void)MPI_Wait(&mpi_request, &status.mpi_status);
  3483. }
  3484.  
  3485. inline void
  3486. _REAL_MPI_::Request::Wait() 
  3487. {
  3488.   (void)MPI_Wait(&mpi_request, &ignored_status.mpi_status);
  3489. }
  3490.  
  3491. inline void
  3492. _REAL_MPI_::Request::Free() 
  3493. {
  3494.   (void)MPI_Request_free(&mpi_request);
  3495. }
  3496.  
  3497. inline MPI2CPP_BOOL_T
  3498. _REAL_MPI_::Request::Test(_REAL_MPI_::Status &status) 
  3499. {
  3500.   int t;
  3501.   (void)MPI_Test(&mpi_request, &t, &status.mpi_status);
  3502.   return (MPI2CPP_BOOL_T) t;
  3503. }
  3504.  
  3505. inline MPI2CPP_BOOL_T
  3506. _REAL_MPI_::Request::Test() 
  3507. {
  3508.   int t;
  3509.   (void)MPI_Test(&mpi_request, &t, &ignored_status.mpi_status);
  3510.   return (MPI2CPP_BOOL_T) t;
  3511. }
  3512.  
  3513. inline int
  3514. _REAL_MPI_::Request::Waitany(int count, _REAL_MPI_::Request array[],
  3515.                  _REAL_MPI_::Status& status)
  3516. {
  3517.   int index, i;
  3518.   MPI_Request* array_of_requests = new MPI_Request[count];
  3519.   for (i=0; i < count; i++)
  3520.     array_of_requests[i] = array[i];
  3521.   (void)MPI_Waitany(count, array_of_requests, &index, &status.mpi_status);
  3522.   for (i=0; i < count; i++)
  3523.     array[i] = array_of_requests[i];
  3524.   delete [] array_of_requests;
  3525.   return index;
  3526. }
  3527.  
  3528. inline int
  3529. _REAL_MPI_::Request::Waitany(int count, _REAL_MPI_::Request array[])
  3530. {
  3531.   int index, i;
  3532.   MPI_Request* array_of_requests = new MPI_Request[count];
  3533.   for (i=0; i < count; i++)
  3534.     array_of_requests[i] = array[i];
  3535.   (void)MPI_Waitany(count, array_of_requests, &index, &ignored_status.mpi_status);
  3536.   for (i=0; i < count; i++)
  3537.     array[i] = array_of_requests[i];
  3538.   delete [] array_of_requests;
  3539.   return index; //JGS, Waitany return value
  3540. }
  3541.  
  3542. inline MPI2CPP_BOOL_T
  3543. _REAL_MPI_::Request::Testany(int count, _REAL_MPI_::Request array[],
  3544.                  int& index, _REAL_MPI_::Status& status)
  3545. {
  3546.   int i, flag;
  3547.   MPI_Request* array_of_requests = new MPI_Request[count];
  3548.   for (i=0; i < count; i++)
  3549.     array_of_requests[i] = array[i];
  3550.   (void)MPI_Testany(count, array_of_requests, &index, &flag, &status.mpi_status);
  3551.   for (i=0; i < count; i++)
  3552.     array[i] = array_of_requests[i];
  3553.   delete [] array_of_requests;
  3554.   return (MPI2CPP_BOOL_T)flag;
  3555. }
  3556.  
  3557. inline MPI2CPP_BOOL_T
  3558. _REAL_MPI_::Request::Testany(int count, _REAL_MPI_::Request array[], int& index)
  3559. {
  3560.   int i, flag;
  3561.   MPI_Request* array_of_requests = new MPI_Request[count];
  3562.   for (i=0; i < count; i++)
  3563.     array_of_requests[i] = array[i];
  3564.   (void)MPI_Testany(count, array_of_requests, &index, &flag, &ignored_status.mpi_status);
  3565.   for (i=0; i < count; i++)
  3566.     array[i] = array_of_requests[i];
  3567.   delete [] array_of_requests;
  3568.   return (MPI2CPP_BOOL_T)flag;
  3569. }
  3570.  
  3571. inline void
  3572. _REAL_MPI_::Request::Waitall(int count, _REAL_MPI_::Request req_array[],
  3573.                  _REAL_MPI_::Status stat_array[])
  3574. {
  3575.   int i;
  3576.   MPI_Request* array_of_requests = new MPI_Request[count];
  3577.   MPI_Status* array_of_statuses = new MPI_Status[count];
  3578.   for (i=0; i < count; i++)
  3579.     array_of_requests[i] = req_array[i];
  3580.   (void)MPI_Waitall(count, array_of_requests, array_of_statuses);
  3581.   for (i=0; i < count; i++)
  3582.     req_array[i] = array_of_requests[i];
  3583.   for (i=0; i < count; i++)
  3584.     stat_array[i] = array_of_statuses[i];
  3585.   delete [] array_of_requests;
  3586.   delete [] array_of_statuses;
  3587. }
  3588.  
  3589. inline void
  3590. _REAL_MPI_::Request::Waitall(int count, _REAL_MPI_::Request req_array[])
  3591. {
  3592.   int i;
  3593.   MPI_Request* array_of_requests = new MPI_Request[count];
  3594.   MPI_Status* array_of_statuses = new MPI_Status[count];
  3595.   for (i=0; i < count; i++)
  3596.     array_of_requests[i] = req_array[i];
  3597.   (void)MPI_Waitall(count, array_of_requests, array_of_statuses);
  3598.   for (i=0; i < count; i++)
  3599.     req_array[i] = array_of_requests[i];
  3600.   delete [] array_of_requests;
  3601.   delete [] array_of_statuses;
  3602.  
  3603. inline MPI2CPP_BOOL_T
  3604. _REAL_MPI_::Request::Testall(int count, _REAL_MPI_::Request req_array[],
  3605.                  _REAL_MPI_::Status stat_array[])
  3606. {
  3607.   int i, flag;
  3608.   MPI_Request* array_of_requests = new MPI_Request[count];
  3609.   MPI_Status* array_of_statuses = new MPI_Status[count];
  3610.   for (i=0; i < count; i++)
  3611.     array_of_requests[i] = req_array[i];
  3612.   (void)MPI_Testall(count, array_of_requests, &flag, array_of_statuses);
  3613.   for (i=0; i < count; i++)
  3614.     req_array[i] = array_of_requests[i];
  3615.   for (i=0; i < count; i++)
  3616.     stat_array[i] = array_of_statuses[i];
  3617.   delete [] array_of_requests;
  3618.   delete [] array_of_statuses;
  3619.   return (MPI2CPP_BOOL_T) flag;
  3620. }
  3621.  
  3622. inline MPI2CPP_BOOL_T
  3623. _REAL_MPI_::Request::Testall(int count, _REAL_MPI_::Request req_array[])
  3624. {
  3625.   int i, flag;
  3626.   MPI_Request* array_of_requests = new MPI_Request[count];
  3627.   MPI_Status* array_of_statuses = new MPI_Status[count];
  3628.   for (i=0; i < count; i++)
  3629.     array_of_requests[i] = req_array[i];
  3630.   (void)MPI_Testall(count, array_of_requests, &flag, array_of_statuses);
  3631.   for (i=0; i < count; i++)
  3632.     req_array[i] = array_of_requests[i];
  3633.   delete [] array_of_requests;
  3634.   delete [] array_of_statuses;
  3635.   return (MPI2CPP_BOOL_T) flag;
  3636.  
  3637. inline int
  3638. _REAL_MPI_::Request::Waitsome(int incount, _REAL_MPI_::Request req_array[],
  3639.                   int array_of_indices[], _REAL_MPI_::Status stat_array[]) 
  3640. {
  3641.   int i, outcount;
  3642.   MPI_Request* array_of_requests = new MPI_Request[incount];
  3643.   MPI_Status* array_of_statuses = new MPI_Status[incount];
  3644.   for (i=0; i < incount; i++)
  3645.     array_of_requests[i] = req_array[i];
  3646.   (void)MPI_Waitsome(incount, array_of_requests, &outcount,
  3647.              array_of_indices, array_of_statuses);
  3648.   for (i=0; i < incount; i++)
  3649.     req_array[i] = array_of_requests[i];
  3650.   for (i=0; i < incount; i++)
  3651.     stat_array[i] = array_of_statuses[i];
  3652.   delete [] array_of_requests;
  3653.   delete [] array_of_statuses;
  3654.   return outcount;
  3655. }
  3656.  
  3657. inline int
  3658. _REAL_MPI_::Request::Waitsome(int incount, _REAL_MPI_::Request req_array[],
  3659.                   int array_of_indices[]) 
  3660. {
  3661.   int i, outcount;
  3662.   MPI_Request* array_of_requests = new MPI_Request[incount];
  3663.   MPI_Status* array_of_statuses = new MPI_Status[incount];
  3664.   for (i=0; i < incount; i++)
  3665.     array_of_requests[i] = req_array[i];
  3666.   (void)MPI_Waitsome(incount, array_of_requests, &outcount,
  3667.              array_of_indices, array_of_statuses);
  3668.   for (i=0; i < incount; i++)
  3669.     req_array[i] = array_of_requests[i];
  3670.   delete [] array_of_requests;
  3671.   delete [] array_of_statuses;
  3672.   return outcount;
  3673. }
  3674.  
  3675. inline int
  3676. _REAL_MPI_::Request::Testsome(int incount, _REAL_MPI_::Request req_array[],
  3677.                   int array_of_indices[], _REAL_MPI_::Status stat_array[]) 
  3678. {
  3679.   int i, outcount;
  3680.   MPI_Request* array_of_requests = new MPI_Request[incount];
  3681.   MPI_Status* array_of_statuses = new MPI_Status[incount];
  3682.   for (i=0; i < incount; i++)
  3683.     array_of_requests[i] = req_array[i];
  3684.   (void)MPI_Testsome(incount, array_of_requests, &outcount,
  3685.              array_of_indices, array_of_statuses);
  3686.   for (i=0; i < incount; i++)
  3687.     req_array[i] = array_of_requests[i];
  3688.   for (i=0; i < incount; i++)
  3689.     stat_array[i] = array_of_statuses[i];
  3690.   delete [] array_of_requests;
  3691.   delete [] array_of_statuses;
  3692.   return outcount;
  3693. }
  3694.  
  3695. inline int
  3696. _REAL_MPI_::Request::Testsome(int incount, _REAL_MPI_::Request req_array[],
  3697.                   int array_of_indices[]) 
  3698. {
  3699.   int i, outcount;
  3700.   MPI_Request* array_of_requests = new MPI_Request[incount];
  3701.   MPI_Status* array_of_statuses = new MPI_Status[incount];
  3702.   for (i=0; i < incount; i++)
  3703.     array_of_requests[i] = req_array[i];
  3704.   (void)MPI_Testsome(incount, array_of_requests, &outcount,
  3705.              array_of_indices, array_of_statuses);
  3706.   for (i=0; i < incount; i++)
  3707.     req_array[i] = array_of_requests[i];
  3708.   delete [] array_of_requests;
  3709.   delete [] array_of_statuses;
  3710.   return outcount;
  3711. }
  3712.  
  3713. inline void
  3714. _REAL_MPI_::Request::Cancel(void) const
  3715. {
  3716.   (void)MPI_Cancel((MPI_Request*)&mpi_request);
  3717. }
  3718.  
  3719. inline void
  3720. _REAL_MPI_::Prequest::Start()
  3721. {
  3722.   (void)MPI_Start(&mpi_request);
  3723. }
  3724.  
  3725. inline void
  3726. _REAL_MPI_::Prequest::Startall(int count, _REAL_MPI_:: Prequest array_of_requests[])
  3727. {
  3728.   //convert the array of Prequests to an array of MPI_requests
  3729.   MPI_Request* mpi_requests = new MPI_Request[count];
  3730.   int i;
  3731.   for (i=0; i < count; i++) {
  3732.     mpi_requests[i] = array_of_requests[i];
  3733.   }
  3734.   (void)MPI_Startall(count, mpi_requests); 
  3735.   for (i=0; i < count; i++)
  3736.     array_of_requests[i].mpi_request = mpi_requests[i] ;
  3737.   delete [] mpi_requests;
  3738.  
  3739. /* process-header: end of request_inln.h */
  3740. /* process-header: including comm_inln.h */
  3741.  
  3742. //
  3743. // Point-to-Point
  3744. //
  3745.  
  3746. inline void
  3747. _REAL_MPI_::Comm::Send(const void *buf, int count, 
  3748.         const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3749. {
  3750.   (void)MPI_Send((void *)buf, count, datatype, dest, tag, mpi_comm);
  3751. }
  3752.  
  3753. inline void
  3754. _REAL_MPI_::Comm::Recv(void *buf, int count, const _REAL_MPI_::Datatype & datatype,
  3755.         int source, int tag, _REAL_MPI_::Status & status) const
  3756. {
  3757.   (void)MPI_Recv(buf, count, datatype, source, tag, mpi_comm, &status.mpi_status);
  3758. }
  3759.  
  3760. inline void
  3761. _REAL_MPI_::Comm::Recv(void *buf, int count, const _REAL_MPI_::Datatype & datatype,
  3762.                     int source, int tag) const
  3763. {
  3764.   (void)MPI_Recv(buf, count, datatype, source, 
  3765.          tag, mpi_comm, &ignored_status.mpi_status);
  3766. }
  3767.  
  3768. inline void
  3769. _REAL_MPI_::Comm::Bsend(const void *buf, int count,
  3770.          const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3771. {
  3772.   (void)MPI_Bsend((void *)buf, count, datatype, 
  3773.           dest, tag, mpi_comm);
  3774. }
  3775.  
  3776. inline void
  3777. _REAL_MPI_::Comm::Ssend(const void *buf, int count, 
  3778.          const _REAL_MPI_::Datatype & datatype, int dest, int tag) const 
  3779. {
  3780.   (void)MPI_Ssend((void *)buf, count,  datatype, dest, 
  3781.           tag, mpi_comm);
  3782. }
  3783.  
  3784. inline void
  3785. _REAL_MPI_::Comm::Rsend(const void *buf, int count,
  3786.          const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3787. {
  3788.   (void)MPI_Rsend((void *)buf, count, datatype, 
  3789.           dest, tag, mpi_comm);
  3790. }
  3791.  
  3792. inline _REAL_MPI_::Request
  3793. _REAL_MPI_::Comm::Isend(const void *buf, int count,
  3794.          const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3795. {
  3796.   MPI_Request request;
  3797.   (void)MPI_Isend((void *)buf, count, datatype, 
  3798.           dest, tag, mpi_comm, &request);
  3799.   return request;
  3800. }
  3801.  
  3802. inline _REAL_MPI_::Request
  3803. _REAL_MPI_::Comm::Ibsend(const void *buf, int count,
  3804.           const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3805. {
  3806.   MPI_Request request;    
  3807.   (void)MPI_Ibsend((void *)buf, count, datatype, 
  3808.            dest, tag, mpi_comm, &request);
  3809.   return request;
  3810. }
  3811.  
  3812. inline _REAL_MPI_::Request
  3813. _REAL_MPI_::Comm::Issend(const void *buf, int count,
  3814.           const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3815. {
  3816.   MPI_Request request;        
  3817.   (void)MPI_Issend((void *)buf, count, datatype,
  3818.            dest, tag, mpi_comm, &request);
  3819.   return request;
  3820. }
  3821.  
  3822. inline _REAL_MPI_::Request
  3823. _REAL_MPI_::Comm::Irsend(const void *buf, int count,
  3824.           const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3825. {
  3826.   MPI_Request request;
  3827.   (void)MPI_Irsend((void *) buf, count, datatype, 
  3828.            dest, tag, mpi_comm, &request);
  3829.   return request;
  3830. }
  3831.  
  3832. inline _REAL_MPI_::Request
  3833. _REAL_MPI_::Comm::Irecv(void *buf, int count,
  3834.          const _REAL_MPI_::Datatype & datatype, int source, int tag) const
  3835. {
  3836.   MPI_Request request;
  3837.   (void)MPI_Irecv(buf, count, datatype, source, 
  3838.           tag, mpi_comm, &request);
  3839.   return request;
  3840. }
  3841.  
  3842.  
  3843. inline MPI2CPP_BOOL_T
  3844. _REAL_MPI_::Comm::Iprobe(int source, int tag, _REAL_MPI_::Status & status) const
  3845. {
  3846.   int t;
  3847.   (void)MPI_Iprobe(source, tag, mpi_comm, &t, &status.mpi_status);
  3848.   return (MPI2CPP_BOOL_T) t;
  3849. }
  3850.   
  3851. inline MPI2CPP_BOOL_T
  3852. _REAL_MPI_::Comm::Iprobe(int source, int tag) const
  3853. {
  3854.   int t;
  3855.   (void)MPI_Iprobe(source, tag, mpi_comm, &t, &ignored_status.mpi_status);
  3856.   return (MPI2CPP_BOOL_T) t;
  3857. }
  3858.  
  3859. inline void
  3860. _REAL_MPI_::Comm::Probe(int source, int tag, _REAL_MPI_::Status & status) const
  3861. {
  3862.   (void)MPI_Probe(source, tag, mpi_comm, &status.mpi_status);
  3863. }
  3864.  
  3865. inline void
  3866. _REAL_MPI_::Comm::Probe(int source, int tag) const
  3867. {
  3868.   (void)MPI_Probe(source, tag, mpi_comm, &ignored_status.mpi_status);  
  3869. }
  3870.  
  3871. inline _REAL_MPI_::Prequest
  3872. _REAL_MPI_::Comm::Send_init(const void *buf, int count,
  3873.              const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3874.   MPI_Request request;
  3875.   (void)MPI_Send_init((void *)buf, count, datatype, 
  3876.               dest, tag, mpi_comm, &request);
  3877.   return request;
  3878. }
  3879.  
  3880. inline _REAL_MPI_::Prequest
  3881. _REAL_MPI_::Comm::Bsend_init(const void *buf, int count,
  3882.               const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3883. {
  3884.   MPI_Request request; 
  3885.   (void)MPI_Bsend_init((void *)buf, count, datatype, 
  3886.                dest, tag, mpi_comm, &request);
  3887.   return request;
  3888. }
  3889.  
  3890. inline _REAL_MPI_::Prequest
  3891. _REAL_MPI_::Comm::Ssend_init(const void *buf, int count,
  3892.               const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3893. {
  3894.   MPI_Request request; 
  3895.   (void)MPI_Ssend_init((void *)buf, count, datatype,
  3896.                dest, tag, mpi_comm, &request);
  3897.   return request;
  3898. }
  3899.  
  3900. inline _REAL_MPI_::Prequest
  3901. _REAL_MPI_::Comm::Rsend_init(const void *buf, int count,
  3902.               const _REAL_MPI_::Datatype & datatype, int dest, int tag) const
  3903. {
  3904.   MPI_Request request; 
  3905.   (void)MPI_Rsend_init((void *)buf, count,  datatype,
  3906.                dest, tag, mpi_comm, &request);
  3907.   return request;
  3908. }
  3909.  
  3910. inline _REAL_MPI_::Prequest
  3911. _REAL_MPI_::Comm::Recv_init(void *buf, int count,
  3912.              const _REAL_MPI_::Datatype & datatype, int source, int tag) const
  3913. {
  3914.   MPI_Request request; 
  3915.   (void)MPI_Recv_init(buf, count, datatype, source, 
  3916.               tag, mpi_comm, &request);
  3917.   return request;
  3918. }
  3919.  
  3920. inline void
  3921. _REAL_MPI_::Comm::Sendrecv(const void *sendbuf, int sendcount,
  3922.             const _REAL_MPI_::Datatype & sendtype, int dest, int sendtag, 
  3923.             void *recvbuf, int recvcount, 
  3924.             const _REAL_MPI_::Datatype & recvtype, int source,
  3925.             int recvtag, _REAL_MPI_::Status & status) const
  3926. {
  3927.   (void)MPI_Sendrecv((void *)sendbuf, sendcount, 
  3928.              sendtype,
  3929.              dest, sendtag, recvbuf, recvcount, 
  3930.              recvtype, 
  3931.              source, recvtag, mpi_comm, &status.mpi_status);
  3932. }
  3933.  
  3934. inline void
  3935. _REAL_MPI_::Comm::Sendrecv(const void *sendbuf, int sendcount,
  3936.             const _REAL_MPI_::Datatype & sendtype, int dest, int sendtag, 
  3937.             void *recvbuf, int recvcount, 
  3938.             const _REAL_MPI_::Datatype & recvtype, int source,
  3939.             int recvtag) const
  3940. {
  3941.   (void)MPI_Sendrecv((void *)sendbuf, sendcount, 
  3942.              sendtype,
  3943.              dest, sendtag, recvbuf, recvcount, 
  3944.              recvtype, 
  3945.              source, recvtag, mpi_comm, &ignored_status.mpi_status);
  3946. }
  3947.  
  3948. inline void
  3949. _REAL_MPI_::Comm::Sendrecv_replace(void *buf, int count,
  3950.                 const _REAL_MPI_::Datatype & datatype, int dest, 
  3951.                 int sendtag, int source,
  3952.                 int recvtag, _REAL_MPI_::Status & status) const 
  3953. {
  3954.   (void)MPI_Sendrecv_replace(buf, count, datatype, dest,
  3955.                  sendtag, source, recvtag, mpi_comm,
  3956.                  &status.mpi_status);
  3957. }
  3958.  
  3959. inline void
  3960. _REAL_MPI_::Comm::Sendrecv_replace(void *buf, int count,
  3961.                 const _REAL_MPI_::Datatype & datatype, int dest, 
  3962.                 int sendtag, int source,
  3963.                 int recvtag) const 
  3964. {
  3965.   (void)MPI_Sendrecv_replace(buf, count, datatype, dest,
  3966.                  sendtag, source, recvtag, mpi_comm,
  3967.                  &ignored_status.mpi_status);    
  3968. }
  3969.  
  3970. //
  3971. // Groups, Contexts, and Communicators
  3972. //
  3973.  
  3974. inline _REAL_MPI_::Group
  3975. _REAL_MPI_::Comm::Get_group() const 
  3976. {
  3977.   MPI_Group group;
  3978.   (void)MPI_Comm_group(mpi_comm, &group);
  3979.   return group;
  3980. }
  3981.   
  3982. inline int
  3983. _REAL_MPI_::Comm::Get_size() const 
  3984. {
  3985.   int size;
  3986.   (void)MPI_Comm_size (mpi_comm, &size);
  3987.   return size;
  3988. }
  3989.   
  3990. inline int
  3991. _REAL_MPI_::Comm::Get_rank() const 
  3992. {
  3993.   int rank;
  3994.   (void)MPI_Comm_rank (mpi_comm, &rank);
  3995.   return rank;
  3996. }
  3997.   
  3998. inline int
  3999. _REAL_MPI_::Comm::Compare(const _REAL_MPI_::Comm & comm1,
  4000.            const _REAL_MPI_::Comm & comm2)
  4001. {
  4002.   int result;
  4003.   (void)MPI_Comm_compare(comm1, comm2, &result);
  4004.   return result;
  4005. }
  4006.  
  4007. inline void
  4008. _REAL_MPI_::Comm::Free(void) 
  4009. {
  4010.   (void)MPI_Comm_free(&mpi_comm);
  4011.   _REAL_MPI_::Comm::mpi_comm_map.erase((void*)mpi_comm);
  4012. }
  4013.   
  4014. inline MPI2CPP_BOOL_T
  4015. _REAL_MPI_::Comm::Is_inter() const
  4016. {
  4017.   int t;
  4018.   (void)MPI_Comm_test_inter(mpi_comm, &t);
  4019.   return (MPI2CPP_BOOL_T) t;
  4020. }
  4021.   
  4022. //
  4023. //Process Topologies
  4024. //
  4025.  
  4026. inline int
  4027. _REAL_MPI_::Comm::Get_topology() const 
  4028. {
  4029.   int status;
  4030.   (void)MPI_Topo_test(mpi_comm, &status);
  4031.   return status;
  4032. }
  4033.   
  4034. //
  4035. // Environmental Inquiry
  4036. //
  4037.  
  4038. inline void
  4039. _REAL_MPI_::Comm::Abort(int errorcode) 
  4040. {
  4041.   (void)MPI_Abort(mpi_comm, errorcode);
  4042. }
  4043.  
  4044. //
  4045. //  These C++ bindings are for MPI-2.
  4046. //  The MPI-1.2 functions called below are all
  4047. //  going to be deprecated and replaced in MPI-2.
  4048. //
  4049.  
  4050. inline void
  4051. _REAL_MPI_::Comm::Set_errhandler(const _REAL_MPI_::Errhandler& errhandler)
  4052. {
  4053.   my_errhandler = (_REAL_MPI_::Errhandler *)&errhandler;
  4054.   _REAL_MPI_::Comm::mpi_comm_map[(void*)mpi_comm] = this;
  4055.   (void)MPI_Errhandler_set(mpi_comm, errhandler);
  4056. }
  4057.  
  4058. inline _REAL_MPI_::Errhandler
  4059. _REAL_MPI_::Comm::Get_errhandler() const
  4060. {
  4061.   return *my_errhandler;
  4062. }
  4063.  
  4064. inline _REAL_MPI_::Errhandler
  4065. _REAL_MPI_::Comm::Create_errhandler(_REAL_MPI_::Comm::ERRHANDLERFN* function)
  4066. {
  4067.   MPI_Errhandler errhandler;
  4068.   (void)MPI_Errhandler_create(errhandler_intercept, &errhandler);
  4069.   _REAL_MPI_::Errhandler temp(errhandler);
  4070.   temp.handler_fn = (void(*)(_REAL_MPI_::Comm&, int*, ...))function;
  4071.   return temp;
  4072. }
  4073.  
  4074. //JGS I took the const out because it causes problems when trying to
  4075. //call this function with the predefined NULL_COPY_FN etc.
  4076. inline int
  4077. _REAL_MPI_::Comm::Create_keyval(_REAL_MPI_::Comm::COPYATTRFN* comm_copy_attr_fn,
  4078.                 _REAL_MPI_::Comm::DELETEATTRFN* comm_delete_attr_fn,
  4079.                 void* extra_state)
  4080. {
  4081.   int keyval;
  4082.   (void)MPI_Keyval_create(copy_attr_intercept, delete_attr_intercept,
  4083.               &keyval, extra_state);
  4084.   MPI_SGI_Map::Pair* copy_and_delete = new MPI_SGI_Map::Pair((void*)comm_copy_attr_fn, (void*)comm_delete_attr_fn); 
  4085.   _REAL_MPI_::Comm::key_fn_map[(MPI_SGI_Map::address)keyval] = copy_and_delete;
  4086.   return keyval;
  4087. }
  4088.  
  4089. inline void
  4090. _REAL_MPI_::Comm::Free_keyval(int& comm_keyval)
  4091. {
  4092.   (void)MPI_Keyval_free(&comm_keyval);
  4093.   _REAL_MPI_::Comm::key_fn_map.erase((void*)comm_keyval);
  4094. }
  4095.  
  4096. inline void
  4097. _REAL_MPI_::Comm::Set_attr(int comm_keyval, const void* attribute_val) const
  4098. {
  4099.   CommType type;
  4100.   int status;
  4101.  
  4102.   (void)MPI_Comm_test_inter(mpi_comm, &status);
  4103.   if (status) {
  4104.     type = eIntercomm;
  4105.   }
  4106.   else {
  4107.     (void)MPI_Topo_test(mpi_comm, &status);    
  4108.     if (status == MPI_CART)
  4109.       type = eCartcomm;
  4110.     else if (status == MPI_GRAPH)
  4111.       type = eGraphcomm;
  4112.     else
  4113.       type = eIntracomm;
  4114.   }
  4115.   MPI_SGI_Map::Pair* comm_type = new MPI_SGI_Map::Pair((void*)this, (void*)type);
  4116.   _REAL_MPI_::Comm::mpi_comm_map[(MPI_SGI_Map::address)mpi_comm] = (MPI_SGI_Map::address)comm_type;
  4117.   (void)MPI_Attr_put(mpi_comm, comm_keyval, (void*)attribute_val);
  4118. }
  4119.  
  4120. inline MPI2CPP_BOOL_T
  4121. _REAL_MPI_::Comm::Get_attr(int comm_keyval, void* attribute_val) const
  4122. {
  4123.   int flag;
  4124.   (void)MPI_Attr_get(mpi_comm, comm_keyval, attribute_val, &flag);
  4125.   return (MPI2CPP_BOOL_T)flag;
  4126. }
  4127.  
  4128. inline void
  4129. _REAL_MPI_::Comm::Delete_attr(int comm_keyval)
  4130. {
  4131.   (void)MPI_Attr_delete(mpi_comm, comm_keyval);
  4132. }
  4133.  
  4134. inline int
  4135. _REAL_MPI_::Comm::NULL_COPY_FN(const _REAL_MPI_::Comm& oldcomm, int comm_keyval,
  4136.                    void* extra_state, void* attribute_val_in,
  4137.                    void* attribute_val_out, MPI2CPP_BOOL_T& flag)
  4138. {
  4139. #if MPI2CPP_IBM_SP
  4140.   //SP2 does not implement this function
  4141.   flag = false;
  4142.   return MPI_SUCCESS;
  4143. #else
  4144.  
  4145. #if _MPIPP_BOOL_NE_INT_
  4146.   int f = (int)flag;
  4147.   int ret;
  4148.   if (MPI_NULL_COPY_FN != 0) {
  4149.     ret = MPI_NULL_COPY_FN(oldcomm, comm_keyval, extra_state, attribute_val_in,
  4150.                attribute_val_out, &f);
  4151.     flag = (MPI2CPP_BOOL_T)f;
  4152.   } else {
  4153.     ret = MPI_SUCCESS;
  4154.     flag = true;
  4155.   }
  4156.   return ret;
  4157. #else
  4158.   if (MPI_NULL_COPY_FN != 0)
  4159.     return MPI_NULL_COPY_FN(oldcomm, comm_keyval, extra_state, 
  4160.                 attribute_val_in, attribute_val_out, (int*)&flag);
  4161.   else
  4162.     return MPI_SUCCESS;
  4163. #endif
  4164.  
  4165. #endif
  4166. }
  4167.  
  4168. inline int
  4169. _REAL_MPI_::Comm::DUP_FN(const _REAL_MPI_::Comm& oldcomm, int comm_keyval,
  4170.              void* extra_state, void* attribute_val_in,
  4171.              void* attribute_val_out, MPI2CPP_BOOL_T& flag)
  4172. {
  4173. #if MPI2CPP_IBM_SP
  4174.   flag = false;
  4175.   return 0;
  4176. #else
  4177. #if _MPIPP_BOOL_NE_INT_
  4178.   int f = (int)flag;
  4179.   int ret;
  4180.   ret = MPI_DUP_FN(oldcomm, comm_keyval, extra_state, attribute_val_in,
  4181.            attribute_val_out, &f);
  4182.   flag = (MPI2CPP_BOOL_T) f;
  4183.   return ret;
  4184. #else
  4185.   return MPI_DUP_FN(oldcomm, comm_keyval, extra_state, attribute_val_in,
  4186.             attribute_val_out, (int*)&flag);
  4187. #endif
  4188. #endif
  4189. }
  4190.  
  4191. inline int
  4192. _REAL_MPI_::Comm::NULL_DELETE_FN(_REAL_MPI_::Comm& comm, int comm_keyval, void* attribute_val,
  4193.                  void* extra_state)
  4194. {
  4195. #if MPI2CPP_IBM_SP
  4196.   return MPI_SUCCESS;
  4197. #else
  4198.   if (MPI_NULL_DELETE_FN != 0)
  4199.     return MPI_NULL_DELETE_FN(comm, comm_keyval, attribute_val, extra_state);
  4200.   else
  4201.     return MPI_SUCCESS;
  4202. #endif
  4203. }
  4204.  
  4205. /* process-header: end of comm_inln.h */
  4206. /* process-header: including intracomm_inln.h */
  4207.  
  4208. inline
  4209. _REAL_MPI_::Intracomm::Intracomm(const MPI_Comm& data) {
  4210.   int flag;
  4211.   if (MPI::Is_initialized() && (data != MPI_COMM_NULL)) {
  4212.     (void)MPI_Comm_test_inter(data, &flag);
  4213.     if (flag)
  4214.       mpi_comm = MPI_COMM_NULL;
  4215.     else
  4216.       mpi_comm = data;
  4217.   }
  4218.   else {
  4219.     mpi_comm = data;
  4220.   }
  4221. }
  4222.  
  4223. //
  4224. // Collective Communication
  4225. //
  4226.  
  4227. inline void
  4228. _REAL_MPI_::Intracomm::Barrier() const
  4229. {
  4230.   (void)MPI_Barrier(mpi_comm);
  4231. }
  4232.  
  4233. inline void
  4234. _REAL_MPI_::Intracomm::Bcast(void *buffer, int count, 
  4235.       const _REAL_MPI_::Datatype& datatype, int root) const
  4236.   (void)MPI_Bcast(buffer, count, datatype, root, mpi_comm);
  4237. }
  4238.  
  4239. inline void
  4240. _REAL_MPI_::Intracomm::Gather(const void *sendbuf, int sendcount, 
  4241.                   const _REAL_MPI_::Datatype & sendtype, 
  4242.                   void *recvbuf, int recvcount, 
  4243.                   const _REAL_MPI_::Datatype & recvtype, int root) const
  4244. {
  4245.   (void)MPI_Gather((void *)sendbuf, sendcount, sendtype,
  4246.            recvbuf, recvcount, recvtype, root, mpi_comm);
  4247. }
  4248.  
  4249. inline void
  4250. _REAL_MPI_::Intracomm::Gatherv(const void *sendbuf, int sendcount, 
  4251.     const _REAL_MPI_::Datatype & sendtype, void *recvbuf, 
  4252.     const int recvcounts[], const int displs[], 
  4253.     const _REAL_MPI_::Datatype & recvtype, int root) const
  4254. {
  4255.   (void)MPI_Gatherv((void *)sendbuf, sendcount,  sendtype,
  4256.             recvbuf, (int *)recvcounts, (int *)displs, 
  4257.             recvtype, root, mpi_comm);
  4258. }
  4259.  
  4260. inline void
  4261. _REAL_MPI_::Intracomm::Scatter(const void *sendbuf, int sendcount, 
  4262.     const _REAL_MPI_::Datatype & sendtype, 
  4263.     void *recvbuf, int recvcount, 
  4264.     const _REAL_MPI_::Datatype & recvtype, int root) const
  4265.   (void)MPI_Scatter((void *)sendbuf, sendcount, sendtype,
  4266.             recvbuf, recvcount, recvtype, root, mpi_comm);
  4267. }
  4268.  
  4269. inline void
  4270. _REAL_MPI_::Intracomm::Scatterv(const void *sendbuf, const int sendcounts[], 
  4271.      const int displs[], const _REAL_MPI_::Datatype & sendtype,
  4272.      void *recvbuf, int recvcount, 
  4273.      const _REAL_MPI_::Datatype & recvtype, int root) const
  4274. {
  4275.   (void)MPI_Scatterv((void *)sendbuf, (int *) sendcounts, 
  4276.              (int *) displs, sendtype, 
  4277.              recvbuf, recvcount, recvtype, 
  4278.              root, mpi_comm);
  4279. }
  4280.  
  4281. inline void
  4282. _REAL_MPI_::Intracomm::Allgather(const void *sendbuf, int sendcount, 
  4283.       const _REAL_MPI_::Datatype & sendtype, void *recvbuf, 
  4284.       int recvcount, const _REAL_MPI_::Datatype & recvtype) const 
  4285. {
  4286.   (void)MPI_Allgather((void *) sendbuf, sendcount, 
  4287.               sendtype, recvbuf, recvcount,
  4288.               recvtype, mpi_comm);
  4289. }
  4290.  
  4291. inline void
  4292. _REAL_MPI_::Intracomm::Allgatherv(const void *sendbuf, int sendcount, 
  4293.        const _REAL_MPI_::Datatype & sendtype, void *recvbuf, 
  4294.        const int recvcounts[], const int displs[],
  4295.        const _REAL_MPI_::Datatype & recvtype) const
  4296. {
  4297.   (void)MPI_Allgatherv((void *)sendbuf, sendcount, 
  4298.                sendtype, recvbuf, 
  4299.                (int *) recvcounts, (int *) displs, 
  4300.                recvtype, mpi_comm);
  4301. }
  4302.  
  4303. inline void
  4304. _REAL_MPI_::Intracomm::Alltoall(const void *sendbuf, int sendcount, 
  4305.      const _REAL_MPI_::Datatype & sendtype, void *recvbuf, 
  4306.      int recvcount, const _REAL_MPI_::Datatype & recvtype) const
  4307. {
  4308.   (void)MPI_Alltoall((void *) sendbuf, sendcount,
  4309.              sendtype, recvbuf, recvcount,
  4310.              recvtype, mpi_comm);
  4311. }
  4312.  
  4313. inline void
  4314. _REAL_MPI_::Intracomm::Alltoallv(const void *sendbuf, const int sendcounts[], 
  4315.       const int sdispls[], const _REAL_MPI_::Datatype & sendtype, 
  4316.       void *recvbuf, const int recvcounts[], 
  4317.       const int rdispls[], const _REAL_MPI_::Datatype & recvtype) const 
  4318. {
  4319.     (void)MPI_Alltoallv((void *) sendbuf, (int *) sendcounts, 
  4320.             (int *) sdispls, sendtype, recvbuf, 
  4321.             (int *) recvcounts, (int *) rdispls, 
  4322.             recvtype,mpi_comm);
  4323. }
  4324.  
  4325.  
  4326. inline void
  4327. _REAL_MPI_::Intracomm::Reduce(const void *sendbuf, void *recvbuf, int count, 
  4328.        const _REAL_MPI_::Datatype & datatype, const _REAL_MPI_::Op& op, 
  4329.        int root) const
  4330. {
  4331.   current_op = (_REAL_MPI_::Op*)&op;
  4332.   (void)MPI_Reduce((void*)sendbuf, recvbuf, count, datatype, op, root, mpi_comm);
  4333.   current_op = (Op*)0;
  4334. }
  4335.  
  4336. inline void
  4337. _REAL_MPI_::Intracomm::Allreduce(const void *sendbuf, void *recvbuf, int count,
  4338.       const _REAL_MPI_::Datatype & datatype, const _REAL_MPI_::Op& op) const
  4339. {
  4340.   current_op = (_REAL_MPI_::Op*)&op;
  4341.   (void)MPI_Allreduce ((void*)sendbuf, recvbuf, count, datatype,  op, mpi_comm);
  4342.   current_op = (Op*)0;
  4343. }
  4344.  
  4345. inline void
  4346. _REAL_MPI_::Intracomm::Reduce_scatter(const void *sendbuf, void *recvbuf, 
  4347.            int recvcounts[], 
  4348.            const _REAL_MPI_::Datatype & datatype, 
  4349.            const _REAL_MPI_::Op& op) const
  4350. {
  4351.   current_op = (_REAL_MPI_::Op*)&op;
  4352.   (void)MPI_Reduce_scatter((void*)sendbuf, recvbuf, recvcounts,
  4353.                datatype, op, mpi_comm);
  4354.   current_op = (Op*)0;
  4355. }
  4356.  
  4357. inline void
  4358. _REAL_MPI_::Intracomm::Scan(const void *sendbuf, void *recvbuf, int count, 
  4359.      const _REAL_MPI_::Datatype & datatype, const _REAL_MPI_::Op& op) const
  4360. {
  4361.   current_op = (_REAL_MPI_::Op*)&op;
  4362.   (void)MPI_Scan((void *)sendbuf, recvbuf, count, datatype, op, mpi_comm);
  4363.   current_op = (Op*)0;
  4364. }
  4365.  
  4366. inline _REAL_MPI_::Intracomm
  4367. _REAL_MPI_::Intracomm::Dup() const
  4368. {
  4369.   MPI_Comm newcomm;
  4370.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4371.   return newcomm;
  4372. }
  4373.  
  4374. #if VIRTUAL_FUNC_RET
  4375. inline _REAL_MPI_::Intracomm&
  4376. _REAL_MPI_::Intracomm::Clone() const
  4377. {
  4378.   MPI_Comm newcomm;
  4379.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4380.   _REAL_MPI_::Intracomm* dup = new _REAL_MPI_::Intracomm(newcomm);
  4381.   return *dup;
  4382. }
  4383. #else
  4384. inline _REAL_MPI_::Comm&
  4385. _REAL_MPI_::Intracomm::Clone() const
  4386. {
  4387.   MPI_Comm newcomm;
  4388.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4389.   _REAL_MPI_::Intracomm* dup = new _REAL_MPI_::Intracomm(newcomm);
  4390.   return *dup;
  4391. }
  4392. #endif
  4393.  
  4394. inline _REAL_MPI_::Intracomm
  4395. _REAL_MPI_::Intracomm::Create(const _REAL_MPI_::Group& group) const
  4396. {
  4397.   MPI_Comm newcomm;
  4398.   (void)MPI_Comm_create(mpi_comm, group, &newcomm);
  4399.   return newcomm;
  4400. }
  4401.  
  4402. inline _REAL_MPI_::Intracomm
  4403. _REAL_MPI_::Intracomm::Split(int color, int key) const
  4404. {
  4405.   MPI_Comm newcomm;
  4406.   (void)MPI_Comm_split(mpi_comm, color, key, &newcomm);
  4407.   return newcomm;
  4408. }
  4409.  
  4410.  
  4411.  
  4412. inline _REAL_MPI_::Intercomm
  4413. _REAL_MPI_::Intracomm::Create_intercomm(int local_leader,
  4414.                     const _REAL_MPI_::Comm& peer_comm,
  4415.                     int remote_leader, int tag) const
  4416. {
  4417.   MPI_Comm newintercomm;
  4418.   (void)MPI_Intercomm_create(mpi_comm, local_leader, peer_comm,
  4419.                  remote_leader, tag, &newintercomm); 
  4420.   return newintercomm;
  4421. }
  4422.  
  4423. inline _REAL_MPI_::Cartcomm
  4424. _REAL_MPI_::Intracomm::Create_cart(int ndims, const int dims[],
  4425.                    const MPI2CPP_BOOL_T periods[], MPI2CPP_BOOL_T reorder) const
  4426. {
  4427.   int *int_periods = new int [ndims];
  4428.   for (int i=0; i<ndims; i++)
  4429.     int_periods[i] = (int) periods[i];
  4430.   
  4431.   MPI_Comm newcomm;
  4432.   (void)MPI_Cart_create(mpi_comm, ndims, (int*)dims, 
  4433.               int_periods, (int)reorder, &newcomm);
  4434.   delete [] int_periods;
  4435.   return newcomm;
  4436. }
  4437.  
  4438. inline _REAL_MPI_::Graphcomm
  4439. _REAL_MPI_::Intracomm::Create_graph(int nnodes, const int index[],
  4440.                     const int edges[], MPI2CPP_BOOL_T reorder) const
  4441. {
  4442.   MPI_Comm newcomm;
  4443.   (void)MPI_Graph_create(mpi_comm, nnodes, (int*)index, 
  4444.                (int*)edges, (int)reorder, &newcomm);
  4445.   return newcomm;
  4446. }
  4447. /* process-header: end of intracomm_inln.h */
  4448. /* process-header: including topology_inln.h */
  4449.  
  4450. //
  4451. //   ========   Cartcomm member functions  ========
  4452. //
  4453.  
  4454. inline
  4455. _REAL_MPI_::Cartcomm::Cartcomm(const MPI_Comm& data) {
  4456.   int status;
  4457.   if (MPI::Is_initialized() && (data != MPI_COMM_NULL)) {
  4458.     (void)MPI_Topo_test(data, &status) ;
  4459.     if (status == MPI_CART)
  4460.       mpi_comm = data;
  4461.     else
  4462.       mpi_comm = MPI_COMM_NULL;
  4463.   }
  4464.   else {
  4465.     mpi_comm = data;
  4466.   }
  4467. }
  4468.  
  4469. //
  4470. // Groups, Contexts, and Communicators
  4471. //
  4472.  
  4473. inline _REAL_MPI_::Cartcomm
  4474. _REAL_MPI_::Cartcomm::Dup() const
  4475. {
  4476.   MPI_Comm newcomm;
  4477.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4478.   return newcomm;
  4479. }
  4480.  
  4481. //
  4482. //  Process Topologies
  4483. //
  4484.  
  4485. inline int
  4486. _REAL_MPI_::Cartcomm::Get_dim() const 
  4487. {
  4488.   int ndims;
  4489.   (void)MPI_Cartdim_get(mpi_comm, &ndims);
  4490.   return ndims;
  4491. }
  4492.  
  4493. inline void
  4494. _REAL_MPI_::Cartcomm::Get_topo(int maxdims, int dims[], MPI2CPP_BOOL_T periods[],
  4495.                    int coords[]) const
  4496. {
  4497.   int *int_periods = new int [maxdims];
  4498.   int i;
  4499.   for (i=0; i<maxdims; i++) {
  4500.     int_periods[i] = (int)periods[i];
  4501.   }
  4502.   (void)MPI_Cart_get(mpi_comm, maxdims, dims, int_periods, coords);
  4503.   for (i=0; i<maxdims; i++) {
  4504.     periods[i] = (MPI2CPP_BOOL_T)int_periods[i];
  4505.   }
  4506.   delete [] int_periods;
  4507. }
  4508.  
  4509. inline int
  4510. _REAL_MPI_::Cartcomm::Get_cart_rank(const int coords[]) const 
  4511. {
  4512.   int rank;
  4513.   (void)MPI_Cart_rank(mpi_comm, (int*)coords, &rank);
  4514.   return rank;
  4515. }
  4516.   
  4517. inline void
  4518. _REAL_MPI_::Cartcomm::Get_coords(int rank, int maxdims, int coords[]) const 
  4519. {
  4520.   (void)MPI_Cart_coords(mpi_comm, rank, maxdims, coords);
  4521.  
  4522. inline void
  4523. _REAL_MPI_::Cartcomm::Shift(int direction, int disp,
  4524.                 int &rank_source, int &rank_dest) const 
  4525. {
  4526.   (void)MPI_Cart_shift(mpi_comm, direction, disp, &rank_source, &rank_dest);
  4527. }
  4528.  
  4529. inline _REAL_MPI_::Cartcomm
  4530. _REAL_MPI_::Cartcomm::Sub(const MPI2CPP_BOOL_T remain_dims[]) 
  4531. {
  4532.   int ndims;
  4533.   MPI_Cartdim_get(mpi_comm, &ndims);
  4534.   int* int_remain_dims = new int[ndims];
  4535.   for (int i=0; i<ndims; i++) {
  4536.     int_remain_dims[i] = (int)remain_dims[i];
  4537.   }
  4538.   MPI_Comm newcomm;
  4539.   (void)MPI_Cart_sub(mpi_comm, int_remain_dims, &newcomm);
  4540.   delete [] int_remain_dims;
  4541.   return newcomm;
  4542. }
  4543.  
  4544. inline int
  4545. _REAL_MPI_::Cartcomm::Map(int ndims, const int dims[], const MPI2CPP_BOOL_T periods[]) const 
  4546. {
  4547.   int *int_periods = new int [ndims];
  4548.   for (int i=0; i<ndims; i++) {
  4549.     int_periods[i] = (int) periods[i];
  4550.   }
  4551.   int newrank;
  4552.   (void)MPI_Cart_map(mpi_comm, ndims, (int*)dims, int_periods, &newrank);
  4553.   delete [] int_periods;
  4554.   return newrank;
  4555. }
  4556.  
  4557.  
  4558. #if VIRTUAL_FUNC_RET
  4559. inline _REAL_MPI_::Cartcomm&
  4560. _REAL_MPI_::Cartcomm::Clone() const
  4561. {
  4562.   MPI_Comm newcomm;
  4563.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4564.   _REAL_MPI_::Cartcomm* dup = new _REAL_MPI_::Cartcomm(newcomm);
  4565.   return *dup;
  4566. }
  4567. #else
  4568. inline _REAL_MPI_::Comm&
  4569. _REAL_MPI_::Cartcomm::Clone() const
  4570. {
  4571.   MPI_Comm newcomm;
  4572.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4573.   _REAL_MPI_::Cartcomm* dup = new _REAL_MPI_::Cartcomm(newcomm);
  4574.   return *dup;
  4575. }
  4576. #endif
  4577.  
  4578. //
  4579. //   ========   Graphcomm member functions  ========
  4580. //
  4581.  
  4582. inline
  4583. _REAL_MPI_::Graphcomm::Graphcomm(const MPI_Comm& data) {
  4584.   int status;
  4585.   if (MPI::Is_initialized() && (data != MPI_COMM_NULL)) {
  4586.     (void)MPI_Topo_test(data, &status) ;
  4587.     if (status == MPI_GRAPH)
  4588.       mpi_comm = data;
  4589.     else
  4590.       mpi_comm = MPI_COMM_NULL;
  4591.   }
  4592.   else {
  4593.     mpi_comm = data;
  4594.   }
  4595. }
  4596.  
  4597. //
  4598. // Groups, Contexts, and Communicators
  4599. //
  4600.  
  4601. inline _REAL_MPI_::Graphcomm
  4602. _REAL_MPI_::Graphcomm::Dup() const
  4603. {
  4604.   MPI_Comm newcomm;
  4605.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4606.   return newcomm;
  4607. }
  4608.  
  4609. //
  4610. //  Process Topologies
  4611. //
  4612.  
  4613. inline void
  4614. _REAL_MPI_::Graphcomm::Get_dims(int nnodes[], int nedges[]) const 
  4615. {
  4616.   (void)MPI_Graphdims_get(mpi_comm, nnodes, nedges);
  4617. }
  4618.  
  4619. inline void
  4620. _REAL_MPI_::Graphcomm::Get_topo(int maxindex, int maxedges, int index[], 
  4621.      int edges[]) const
  4622. {
  4623.   (void)MPI_Graph_get(mpi_comm, maxindex, maxedges, index, edges);
  4624. }
  4625.  
  4626. inline int
  4627. _REAL_MPI_::Graphcomm::Get_neighbors_count(int rank) const 
  4628. {
  4629.   int nneighbors;
  4630.   (void)MPI_Graph_neighbors_count(mpi_comm, rank, &nneighbors);
  4631.   return nneighbors;
  4632. }
  4633.  
  4634. inline void
  4635. _REAL_MPI_::Graphcomm::Get_neighbors(int rank, int maxneighbors, 
  4636.           int neighbors[]) const 
  4637. {
  4638.   (void)MPI_Graph_neighbors(mpi_comm, rank, maxneighbors, neighbors);
  4639. }
  4640.  
  4641. inline int
  4642. _REAL_MPI_::Graphcomm::Map(int nnodes, const int index[], 
  4643.     const int edges[]) const 
  4644. {
  4645.   int newrank;
  4646.   (void)MPI_Graph_map(mpi_comm, nnodes, (int*)index, (int*)edges, &newrank);
  4647.   return newrank;
  4648. }
  4649.  
  4650. #if VIRTUAL_FUNC_RET
  4651. inline _REAL_MPI_::Graphcomm&
  4652. _REAL_MPI_::Graphcomm::Clone() const
  4653. {
  4654.   MPI_Comm newcomm;
  4655.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4656.   _REAL_MPI_::Graphcomm* dup = new _REAL_MPI_::Graphcomm(newcomm);
  4657.   return *dup;
  4658. }
  4659. #else
  4660. inline _REAL_MPI_::Comm&
  4661. _REAL_MPI_::Graphcomm::Clone() const
  4662. {
  4663.   MPI_Comm newcomm;
  4664.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4665.   _REAL_MPI_::Graphcomm* dup = new _REAL_MPI_::Graphcomm(newcomm);
  4666.   return *dup;
  4667. }
  4668. #endif
  4669. /* process-header: end of topology_inln.h */
  4670. /* process-header: including intercomm_inln.h */
  4671.  
  4672. inline _REAL_MPI_::Intercomm
  4673. _REAL_MPI_::Intercomm::Dup() const
  4674. {
  4675.   MPI_Comm newcomm;
  4676.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4677.   return newcomm;
  4678. }
  4679.  
  4680. #if VIRTUAL_FUNC_RET
  4681. inline _REAL_MPI_::Intercomm&
  4682. _REAL_MPI_::Intercomm::Clone() const
  4683. {
  4684.   MPI_Comm newcomm;
  4685.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4686.   _REAL_MPI_::Intercomm* dup = new _REAL_MPI_::Intercomm(newcomm);
  4687.   return *dup;
  4688. }
  4689. #else
  4690. inline _REAL_MPI_::Comm&
  4691. _REAL_MPI_::Intercomm::Clone() const
  4692. {
  4693.   MPI_Comm newcomm;
  4694.   (void)MPI_Comm_dup(mpi_comm, &newcomm);
  4695.   _REAL_MPI_::Intercomm* dup = new _REAL_MPI_::Intercomm(newcomm);
  4696.   return *dup;
  4697. }
  4698. #endif
  4699.  
  4700. inline int
  4701. _REAL_MPI_::Intercomm::Get_remote_size() const 
  4702. {
  4703.   int size;
  4704.   (void)MPI_Comm_remote_size(mpi_comm, &size);
  4705.   return size;
  4706. }
  4707.  
  4708. inline _REAL_MPI_::Group
  4709. _REAL_MPI_::Intercomm::Get_remote_group() const 
  4710. {
  4711.   MPI_Group group;
  4712.   (void)MPI_Comm_remote_group(mpi_comm, &group);
  4713.   return group;
  4714. }
  4715.  
  4716. inline _REAL_MPI_::Intracomm
  4717. _REAL_MPI_::Intercomm::Merge(MPI2CPP_BOOL_T high) 
  4718. {
  4719.   MPI_Comm newcomm;
  4720.   (void)MPI_Intercomm_merge(mpi_comm, (int)high, &newcomm);
  4721.   return newcomm;
  4722. }
  4723.  
  4724. /* process-header: end of intercomm_inln.h */
  4725. /* process-header: including group_inln.h */
  4726.  
  4727. //
  4728. // Groups, Contexts, and Communicators
  4729. //
  4730.  
  4731. inline int
  4732. _REAL_MPI_::Group::Get_size() const
  4733. {
  4734.   int size;
  4735.   (void)MPI_Group_size(mpi_group, &size);
  4736.   return size;
  4737. }
  4738.  
  4739. inline int
  4740. _REAL_MPI_::Group::Get_rank() const 
  4741. {
  4742.   int rank;
  4743.   (void)MPI_Group_rank(mpi_group, &rank);
  4744.   return rank;
  4745. }
  4746.  
  4747. inline void
  4748. _REAL_MPI_::Group::Translate_ranks (const _REAL_MPI_::Group& group1, int n,
  4749.                     const int ranks1[], 
  4750.                     const _REAL_MPI_::Group& group2, int ranks2[])
  4751. {
  4752.   (void)MPI_Group_translate_ranks(group1, n, (int*)ranks1, group2, (int*)ranks2);
  4753. }
  4754.  
  4755. inline int
  4756. _REAL_MPI_::Group::Compare(const _REAL_MPI_::Group& group1, const _REAL_MPI_::Group& group2)
  4757. {
  4758.   int result;
  4759.   (void)MPI_Group_compare(group1, group2, &result);
  4760.   return result;
  4761. }
  4762.  
  4763. inline _REAL_MPI_::Group
  4764. _REAL_MPI_::Group::Union(const _REAL_MPI_::Group &group1, const _REAL_MPI_::Group &group2)
  4765. {
  4766.   MPI_Group newgroup;
  4767.   (void)MPI_Group_union(group1, group2, &newgroup);
  4768.   return newgroup;
  4769. }
  4770.  
  4771. inline _REAL_MPI_::Group
  4772. _REAL_MPI_::Group::Intersect(const _REAL_MPI_::Group &group1, const _REAL_MPI_::Group &group2)
  4773. {
  4774.   MPI_Group newgroup;
  4775.   (void)MPI_Group_intersection( group1,  group2, &newgroup);
  4776.   return newgroup;
  4777. }
  4778.  
  4779. inline _REAL_MPI_::Group
  4780. _REAL_MPI_::Group::Difference(const _REAL_MPI_::Group &group1, const _REAL_MPI_::Group &group2)
  4781. {
  4782.   MPI_Group newgroup;  
  4783.   (void)MPI_Group_difference(group1, group2, &newgroup);
  4784.   return newgroup;
  4785. }
  4786.  
  4787. inline _REAL_MPI_::Group
  4788. _REAL_MPI_::Group::Incl(int n, const int ranks[]) const
  4789. {
  4790.   MPI_Group newgroup;
  4791.   (void)MPI_Group_incl(mpi_group, n, (int*)ranks, &newgroup);
  4792.   return newgroup;
  4793. }
  4794.  
  4795. inline _REAL_MPI_::Group
  4796. _REAL_MPI_::Group::Excl(int n, const int ranks[]) const
  4797. {
  4798.   MPI_Group newgroup;
  4799.   (void)MPI_Group_excl(mpi_group, n, (int*)ranks, &newgroup);
  4800.   return newgroup;
  4801. }
  4802.  
  4803. inline _REAL_MPI_::Group
  4804. _REAL_MPI_::Group::Range_incl(int n, const int ranges[][3]) const
  4805. {
  4806.   MPI_Group newgroup;
  4807.   (void)MPI_Group_range_incl(mpi_group, n, (int(*)[3])ranges, &newgroup);
  4808.   return newgroup;
  4809. }
  4810.  
  4811. inline _REAL_MPI_::Group
  4812. _REAL_MPI_::Group::Range_excl(int n, const int ranges[][3]) const
  4813. {
  4814.   MPI_Group newgroup;
  4815.   (void)MPI_Group_range_excl(mpi_group, n, (int(*)[3])ranges, &newgroup);
  4816.   return newgroup;
  4817. }
  4818.  
  4819. inline void
  4820. _REAL_MPI_::Group::Free()
  4821. {
  4822.   (void)MPI_Group_free(&mpi_group);
  4823. }
  4824. /* process-header: end of group_inln.h */
  4825. /* process-header: including op_inln.h */
  4826.  
  4827. #if _MPIPP_PROFILING_
  4828.  
  4829. inline
  4830. MPI::Op::Op() { }
  4831.   
  4832. inline
  4833. MPI::Op::Op(const MPI::Op& o) : pmpi_op(o.pmpi_op) { }
  4834.   
  4835. inline
  4836. MPI::Op::Op(const MPI_Op& o) : pmpi_op(o) { }
  4837.  
  4838. inline
  4839. MPI::Op::~Op() { }
  4840.  
  4841. inline
  4842. MPI::Op& MPI::Op::operator=(const MPI::Op& op) {
  4843.   pmpi_op = op.pmpi_op; return *this;
  4844. }
  4845.  
  4846. // comparison
  4847. inline MPI2CPP_BOOL_T
  4848. MPI::Op::operator== (const MPI::Op &a) {
  4849.   return (MPI2CPP_BOOL_T)(pmpi_op == a);
  4850. }
  4851.  
  4852. inline MPI2CPP_BOOL_T
  4853. MPI::Op::operator!= (const MPI::Op &a) {
  4854.   return (MPI2CPP_BOOL_T)!(*this == a);
  4855. }
  4856.  
  4857. // inter-language operability
  4858. inline MPI::Op&
  4859. MPI::Op::operator= (const MPI_Op &i) { pmpi_op = i; return *this; }
  4860.  
  4861. inline
  4862. MPI::Op::operator MPI_Op () const { return pmpi_op; }
  4863.  
  4864. //inline
  4865. //MPI::Op::operator MPI_Op* () { return pmpi_op; }
  4866.  
  4867.  
  4868. #else  // ============= NO PROFILING ===================================
  4869.  
  4870. // construction
  4871. inline
  4872. MPI::Op::Op() : mpi_op(MPI_OP_NULL) { }
  4873.  
  4874. inline
  4875. MPI::Op::Op(const MPI_Op &i) : mpi_op(i) { }
  4876.  
  4877. inline
  4878. MPI::Op::Op(const MPI::Op& op)
  4879.   : op_user_function(op.op_user_function), mpi_op(op.mpi_op) { }
  4880.  
  4881. inline 
  4882. MPI::Op::~Op() 
  4883. #if _MPIPP_DEBUG_
  4884.   mpi_op = MPI_OP_NULL;
  4885.   op_user_function = 0;
  4886. #endif
  4887. }  
  4888.  
  4889. inline MPI::Op&
  4890. MPI::Op::operator=(const MPI::Op& op) {
  4891.   mpi_op = op.mpi_op;
  4892.   op_user_function = op.op_user_function;
  4893.   return *this;
  4894. }
  4895.  
  4896. // comparison
  4897. inline MPI2CPP_BOOL_T
  4898. MPI::Op::operator== (const MPI::Op &a) { return (MPI2CPP_BOOL_T)(mpi_op == a.mpi_op); }
  4899.  
  4900. inline MPI2CPP_BOOL_T
  4901. MPI::Op::operator!= (const MPI::Op &a) { return (MPI2CPP_BOOL_T)!(*this == a); }
  4902.  
  4903. // inter-language operability
  4904. inline MPI::Op&
  4905. MPI::Op::operator= (const MPI_Op &i) { mpi_op = i; return *this; }
  4906.  
  4907. inline
  4908. MPI::Op::operator MPI_Op () const { return mpi_op; }
  4909.  
  4910. //inline
  4911. //MPI::Op::operator MPI_Op* () { return &mpi_op; }
  4912.  
  4913. #endif
  4914.  
  4915.  
  4916.  
  4917. inline void
  4918. _REAL_MPI_::Op::Init(_REAL_MPI_::User_function *func, MPI2CPP_BOOL_T commute)
  4919. {
  4920.   (void)MPI_Op_create(op_intercept , (int) commute, &mpi_op);
  4921.   op_user_function = (User_function*)func;
  4922. }
  4923.  
  4924.  
  4925. inline void
  4926. _REAL_MPI_::Op::Free()
  4927. {
  4928.   (void)MPI_Op_free(&mpi_op);
  4929. }
  4930.  
  4931.  
  4932.  
  4933.  
  4934.  
  4935. /* process-header: end of op_inln.h */
  4936. /* process-header: including errhandler_inln.h */
  4937.  
  4938. #if _MPIPP_PROFILING_
  4939.  
  4940. inline PMPI::Errhandler::Errhandler(const PMPI::Errhandler& e)
  4941.   : mpi_errhandler(e.mpi_errhandler), handler_fn(e.handler_fn) { }
  4942.  
  4943. inline PMPI::Errhandler&
  4944. PMPI::Errhandler::operator=(const PMPI::Errhandler& e)
  4945. {
  4946.   handler_fn = e.handler_fn;
  4947.   mpi_errhandler = e.mpi_errhandler;
  4948.   return *this;
  4949. }
  4950.  
  4951. inline MPI2CPP_BOOL_T
  4952. PMPI::Errhandler::operator==(const PMPI::Errhandler &a)
  4953. {
  4954.   return (MPI2CPP_BOOL_T)(mpi_errhandler == a.mpi_errhandler);
  4955. }
  4956.  
  4957. #endif
  4958.  
  4959. inline void
  4960. _REAL_MPI_::Errhandler::Free()
  4961. {
  4962.   (void)MPI_Errhandler_free(&mpi_errhandler);
  4963. }
  4964.  
  4965.  
  4966.  
  4967.  
  4968. /* process-header: end of errhandler_inln.h */
  4969. /* process-header: including status_inln.h */
  4970.  
  4971. //
  4972. // Point-to-Point Communication
  4973. //
  4974.  
  4975. inline int
  4976. _REAL_MPI_::Status::Get_count(const _REAL_MPI_::Datatype& datatype) const
  4977. {
  4978.   int count;
  4979.   //(MPI_Status*) is to cast away the const
  4980.   (void)MPI_Get_count((MPI_Status*)&mpi_status, datatype, &count);
  4981.   return count;
  4982. }
  4983.  
  4984. inline MPI2CPP_BOOL_T
  4985. _REAL_MPI_::Status::Is_cancelled() const
  4986. {
  4987.   int t;
  4988.   (void)MPI_Test_cancelled((MPI_Status*)&mpi_status, &t);
  4989.   return (MPI2CPP_BOOL_T) t;
  4990. }
  4991.  
  4992. inline int
  4993. _REAL_MPI_::Status::Get_elements(const _REAL_MPI_::Datatype& datatype) const
  4994. {
  4995.   int count;
  4996.   (void)MPI_Get_elements((MPI_Status*)&mpi_status, datatype, &count);
  4997.   return count;
  4998. }
  4999.  
  5000. //
  5001. // Status Access
  5002. //
  5003. inline int
  5004. _REAL_MPI_::Status::Get_source() const
  5005. {
  5006.   int source;
  5007.   source = mpi_status.MPI_SOURCE;
  5008.   return source;
  5009. }
  5010.  
  5011. inline void
  5012. _REAL_MPI_::Status::Set_source(int source)
  5013. {
  5014.   mpi_status.MPI_SOURCE = source;
  5015. }
  5016.  
  5017. inline int
  5018. _REAL_MPI_::Status::Get_tag() const
  5019. {
  5020.   int tag;
  5021.   tag = mpi_status.MPI_TAG;
  5022.   return tag;
  5023. }
  5024.  
  5025. inline void
  5026. _REAL_MPI_::Status::Set_tag(int tag)
  5027. {
  5028.   mpi_status.MPI_TAG = tag;
  5029. }
  5030.  
  5031. inline int
  5032. _REAL_MPI_::Status::Get_error() const
  5033. {
  5034.   int error;
  5035.   error = mpi_status.MPI_ERROR;
  5036.   return error;
  5037. }
  5038.  
  5039. inline void
  5040. _REAL_MPI_::Status::Set_error(int error)
  5041. {
  5042.   mpi_status.MPI_ERROR = error;
  5043. }
  5044. /* process-header: end of status_inln.h */
  5045.  
  5046. #endif
  5047.  
  5048.  
  5049.